From e9ca9821bb963dcb9391a6340cd07ab9dc458e9b Mon Sep 17 00:00:00 2001 From: Aidan Timson Date: Wed, 24 Feb 2021 22:29:50 +0000 Subject: [PATCH 01/90] Update Lyric docs to use config flow include (#16735) --- source/_integrations/lyric.markdown | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/source/_integrations/lyric.markdown b/source/_integrations/lyric.markdown index 583fe46e553..c274d0328c0 100644 --- a/source/_integrations/lyric.markdown +++ b/source/_integrations/lyric.markdown @@ -34,12 +34,7 @@ lyric: You can then add the integration in the frontend. -## Configuration - -Menu: **Configuration** -> **Integrations**. - -Click on the `+` sign to add an integration and click on **Honeywell Lyric**. -Log in with your Honeywell Lyric account and agree to the terms. The Honeywell Lyric integration will then be available. +{% include integrations/config_flow.md %} ## Sensors From 9694859482ff88fe81e41f48fdb7cda800940e34 Mon Sep 17 00:00:00 2001 From: Nathan Spencer Date: Wed, 24 Feb 2021 18:03:49 -0700 Subject: [PATCH 02/90] Adjust wording and add ha_platforms in Litter-Robot documentation (#16737) --- source/_integrations/litterrobot.markdown | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/_integrations/litterrobot.markdown b/source/_integrations/litterrobot.markdown index b5def7d9fff..96e769609ae 100644 --- a/source/_integrations/litterrobot.markdown +++ b/source/_integrations/litterrobot.markdown @@ -10,21 +10,23 @@ ha_quality_scale: gold ha_codeowners: - '@natekspencer' ha_domain: litterrobot +ha_platforms: + - sensor + - switch + - vacuum --- The Litter-Robot integration allows you to control and monitor your Wi-Fi-enabled, automatic, self-cleaning litter box for cats. You will need a Litter-Robot account as well as a Wi-Fi-enabled Litter-Robot unit that has already been associated with your account. -There is currently support for the following device types within Home Assistant: - -- Vacuum (this is the representation of your Litter-Robot litter box) +The Feeder-Robot is not currently supported by this integration. {% include integrations/config_flow.md %} ## Entities -The following entities are created for this component: +The following entities are created for this component and identified by a single device per Litter-Robot unit: | Entity | Domain | Description | | ---------------- | -------- | -------------------------------------------------------------------------------- | @@ -33,15 +35,13 @@ The following entities are created for this component: | Panel Lockout | `switch` | When turned on, disables the buttons on the unit to prevent changes to settings. | | Waste Drawer | `sensor` | Displays the current waste level gauge. | -All of the entities above are grouped together and identified by a single device. - -## Attributes +## Additional Attributes Some entities have attributes in addition to the default ones that are available for that platform. They are listed below. ### Litter Box `vacuum` entity -| Attribute | Type | Definition | +| Attribute | Type | Description | | ----------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | clean_cycle_wait_time_minutes | integer | Current wait time, in minutes, between when your cat uses the Litter-Robot and when the unit cycles automatically. | | is_sleeping | boolean | Whether or not the unit is currently in sleep mode. | @@ -53,7 +53,7 @@ Some entities have attributes in addition to the default ones that are available ### Waste Drawer `sensor` entity -| Attribute | Type | Definition | +| Attribute | Type | Description | | ------------------------ | ------- | ------------------------------------------------------------------------ | | cycle_count | integer | Number of clean cycles performed since last reset. | | cycle_capacity | integer | Number of clean cycles before unit is full. | @@ -61,7 +61,7 @@ Some entities have attributes in addition to the default ones that are available ## Commands -In addition to the entities that are created above, some commands are utilized for additional functionality that is available in the Litter-Robot companion app. +Commands are utilized for additional functionality that is available in the Litter-Robot companion app. The following are currently available: ### reset_waste_drawer From c0b7a9b0a41b21078a0d7f20579844f16c5bf376 Mon Sep 17 00:00:00 2001 From: starkillerOG Date: Thu, 25 Feb 2021 13:18:31 +0100 Subject: [PATCH 03/90] Add Xiaomi Miio fan config flow (#16683) --- source/_integrations/xiaomi_miio.markdown | 38 +++++------------------ 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/source/_integrations/xiaomi_miio.markdown b/source/_integrations/xiaomi_miio.markdown index c08b76da899..c2e4adad542 100644 --- a/source/_integrations/xiaomi_miio.markdown +++ b/source/_integrations/xiaomi_miio.markdown @@ -350,6 +350,13 @@ Supported devices: | Air Humidifier CB1 | zhimi.humidifier.cb1 | | | Air Fresh VA2 | zhimi.airfresh.va2 | | + +### Configuration + +Please follow the instructions on [Retrieving the Access Token](/integrations/xiaomi_miio/#retrieving-the-access-token) to get the API token to use during configuration flow setup. + +To add a Xiaomi Air Purifier to your installation, click Configuration in the sidebar, then click Integrations and then click the + icon in the lower right and find xiaomi_miio. You will then be presented with a form in which you will need to fill in the “IP address” and 32 characters “token”. After you click submit, you will have the opportunity to select the area that your devices are located. + ### Features ### Air Purifier 2 et al. @@ -677,37 +684,6 @@ This model uses newer MiOT communication protocol. - `motor_speed` - `extra_features` -Please follow the instructions on [Retrieving the Access Token](/integrations/xiaomi_miio/#retrieving-the-access-token) to get the API token to use in the `configuration.yaml` file. - -To add a Xiaomi Air Purifier to your installation, add the following to your `configuration.yaml` file: - -```yaml -fan: -# Example configuration.yaml entry - - platform: xiaomi_miio - host: 192.168.130.66 - token: YOUR_TOKEN -``` - -{% configuration %} -host: - description: The IP address of your miio fan. - required: true - type: string -token: - description: The API token of your miio fan. - required: true - type: string -name: - description: The name of your miio fan. - required: false - type: string - default: Xiaomi Air Purifier -model: - description: The model of your miio fan. See the table above for valid values (f.e. `zhimi.airpurifier.v2`). This setting can be used to bypass the device model detection and is recommended if your device isn't always available. - required: false - type: string -{% endconfiguration %} ### Platform Services From d1294d1b840f6eec21ab62560820176d193a178f Mon Sep 17 00:00:00 2001 From: Hmmbob <33529490+hmmbob@users.noreply.github.com> Date: Thu, 25 Feb 2021 13:44:20 +0100 Subject: [PATCH 04/90] Remove docs for removed keyring/credstash options (#16745) --- source/_docs/configuration/secrets.markdown | 8 +--- source/_docs/tools/credstash.markdown | 35 ------------------ source/_docs/tools/keyring.markdown | 39 -------------------- source/_includes/asides/docs_navigation.html | 2 - source/_redirects | 2 + 5 files changed, 3 insertions(+), 83 deletions(-) delete mode 100644 source/_docs/tools/credstash.markdown delete mode 100644 source/_docs/tools/keyring.markdown diff --git a/source/_docs/configuration/secrets.markdown b/source/_docs/configuration/secrets.markdown index 23a68d3c837..8dec4f4c6c5 100644 --- a/source/_docs/configuration/secrets.markdown +++ b/source/_docs/configuration/secrets.markdown @@ -38,8 +38,7 @@ http_password: YOUR_PASSWORD When you start splitting your configuration into multiple files, you might end up with configuration in sub folders. Secrets will be resolved in this order: - A `secrets.yaml` located in the same folder as the YAML file referencing the secret, -- next, parent folders will be searched for a `secrets.yaml` file with the secret, stopping at the folder with the main `configuration.yaml`, -- lastly, `keyring` will be queried for the secret (more info below). +- next, parent folders will be searched for a `secrets.yaml` file with the secret, stopping at the folder with the main `configuration.yaml`. To see where secrets are being loaded from, you can either add an option to your `secrets.yaml` file or use the `check_config` script. @@ -58,8 +57,3 @@ hass --script check_config --secrets ``` This will print all your secrets. - -## Alternatives to `secrets.yaml` - -- [Using a keyring that is managed by your OS to store secrets](/docs/tools/keyring/) -- [Storing passwords securely in AWS](/docs/tools/credstash/) diff --git a/source/_docs/tools/credstash.markdown b/source/_docs/tools/credstash.markdown deleted file mode 100644 index 5560cd7d39e..00000000000 --- a/source/_docs/tools/credstash.markdown +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: "credstash" -description: "Script to store credentials securely in AWS" ---- - -

-This feature has been deprecated and will be removed in March 2021. -

- -Using [Credstash](https://github.com/fugue/credstash) is an alternative way to `secrets.yaml`. They can be managed from the command line via the credstash script. - -Before using credstash, you need to set up AWS credentials either via the `aws` command line tool or using environment variables as explained in the [AWS CLI documentation](http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html) as well as creating a KMS key named `credstash` as explained in the [credstash Readme](https://github.com/fugue/credstash#setting-up-kms). After that is complete, you can use the provided script to add secrets to your Home Assistant secret store in credstash. - -```bash -hass --script credstash --help -``` - -To store a password in credstash, replace your password or API key with `!secret` and an identifier in `configuration.yaml` file. - -```yaml -example: - password: !secret example_password -``` - -Create an entry in your credstash store. - -```bash -hass --script credstash put http_password 123 -``` - -List your secrets. - -```bash -hass --script credstash list -``` diff --git a/source/_docs/tools/keyring.markdown b/source/_docs/tools/keyring.markdown deleted file mode 100644 index c146440ae20..00000000000 --- a/source/_docs/tools/keyring.markdown +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "keyring" -description: "Script to store secrets in a keyring" ---- - -

-This feature has been deprecated and will be removed in March 2021. -

- -Using [Keyring](https://github.com/jaraco/keyring) is an alternative way to `secrets.yaml`. The secrets can be managed from the command line via the `keyring` script. - -```bash -hass --script keyring --help -``` - -To store a password in keyring, replace your password or API key with `!secret` and an identifier in `configuration.yaml` file. - -```yaml -integration1: - api_key: !secret integration1_key -``` - -Create an entry in your keyring. - -```bash -hass --script keyring set integration1_key -``` - -If you launch Home Assistant now, you will be prompted for the keyring password to unlock your keyring. - -```bash -$ hass -Config directory: /home/homeassistant/.homeassistant -Please enter password for encrypted keyring: -``` - -
-If you are using the Python Keyring, automatic starting of Home Assistant Core will no longer work. -
diff --git a/source/_includes/asides/docs_navigation.html b/source/_includes/asides/docs_navigation.html index 632e1dd4461..a7546728ac3 100644 --- a/source/_includes/asides/docs_navigation.html +++ b/source/_includes/asides/docs_navigation.html @@ -146,8 +146,6 @@
  • {% active_link /docs/tools/quick-bar/ Quick Bar %}
  • {% active_link /docs/tools/hass/ hass %}
  • {% active_link /docs/tools/check_config/ check_config %}
  • -
  • {% active_link /docs/tools/credstash/ credstash %}
  • -
  • {% active_link /docs/tools/keyring/ keyring %}
  • diff --git a/source/_redirects b/source/_redirects index 89a69feb219..f4bc0b59b4a 100644 --- a/source/_redirects +++ b/source/_redirects @@ -2190,6 +2190,8 @@ /docs/installation/raspberry-pi-all-in-one /getting-started /getting-started/hassbian /getting-started /getting-started/installation-raspberry-pi-all-in-one /getting-started +/docs/tools/keyring/ /docs/configuration/secrets +/docs/tools/credstash/ /docs/configuration/secrets # Blog /blog/2019/05/29/release-94 /blog/2019/06/05/release-94 From 0e86e8e9e5a17dddbb1868ccd344f1971288f96b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Thu, 25 Feb 2021 16:28:03 +0100 Subject: [PATCH 05/90] Fix style for my integration button (#16746) --- sass/custom/_paulus.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sass/custom/_paulus.scss b/sass/custom/_paulus.scss index 8c37c81f9fe..e313c289ff9 100644 --- a/sass/custom/_paulus.scss +++ b/sass/custom/_paulus.scss @@ -460,6 +460,8 @@ div.note { .brand-logo-container { text-align: center; margin-top: 50px; + display: grid; + justify-items: center; img { max-height: 67px; From 5e595693508f0e6eeea783c845bfaad7b8d5eb4b Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Fri, 26 Feb 2021 10:41:26 +0100 Subject: [PATCH 06/90] Document value_template in MQTT triggers (#16754) --- source/_docs/automation/trigger.markdown | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/_docs/automation/trigger.markdown b/source/_docs/automation/trigger.markdown index 04e7bc51363..75d5c6471b8 100644 --- a/source/_docs/automation/trigger.markdown +++ b/source/_docs/automation/trigger.markdown @@ -97,6 +97,18 @@ automation: encoding: "utf-8" ``` +The `payload` option can be combined with a `value_template` to process the message received on the given MQTT topic before matching it with the payload. +The trigger in the example below will trigger only when the message received on `living_room/switch/ac` is valid JSON, with a key `state` which has the value `"on"`. + +```yaml +automation: + trigger: + platform: mqtt + topic: "living_room/switch/ac" + payload: "on" + value_template: "{{ value_json.state }}" +``` + It's also possible to use [limited templates](/docs/configuration/templating/#limited-templates) in the `topic` and `payload` options.
    From 39d3a758aee2719af8948016ccca7b0cfb5c3f21 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Fri, 26 Feb 2021 10:49:35 +0100 Subject: [PATCH 07/90] Fix MQTT trigger value_template example (#16755) --- source/_docs/automation/trigger.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/_docs/automation/trigger.markdown b/source/_docs/automation/trigger.markdown index 75d5c6471b8..d4642e31cd1 100644 --- a/source/_docs/automation/trigger.markdown +++ b/source/_docs/automation/trigger.markdown @@ -100,6 +100,8 @@ automation: The `payload` option can be combined with a `value_template` to process the message received on the given MQTT topic before matching it with the payload. The trigger in the example below will trigger only when the message received on `living_room/switch/ac` is valid JSON, with a key `state` which has the value `"on"`. +{% raw %} + ```yaml automation: trigger: @@ -109,6 +111,8 @@ automation: value_template: "{{ value_json.state }}" ``` +{% endraw %} + It's also possible to use [limited templates](/docs/configuration/templating/#limited-templates) in the `topic` and `payload` options.
    From 268f1fb25e6300e49489ea183c893f1cb99be801 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Fri, 26 Feb 2021 18:35:06 +0100 Subject: [PATCH 08/90] Add support for v6 features to philips js integration (#16628) Co-authored-by: Klaas Schoute --- source/_integrations/philips_js.markdown | 27 +++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/source/_integrations/philips_js.markdown b/source/_integrations/philips_js.markdown index b4aa566e996..aa3316e9a17 100644 --- a/source/_integrations/philips_js.markdown +++ b/source/_integrations/philips_js.markdown @@ -11,10 +11,31 @@ ha_domain: philips_js ha_config_flow: true --- -The `philips_js` platform allows you to control Philips TVs which expose the [jointSPACE](http://jointspace.sourceforge.net/) JSON-API. Instructions on how to activate the API and if your model is supported can be found [here](http://jointspace.sourceforge.net/download.html). Note that not all listed, jointSPACE-enabled devices will have JSON-interface running on port 1925. This is true at least for some models before year 2011. +The `philips_js` platform allows you to control Philips TVs which expose the [jointSPACE](http://jointspace.sourceforge.net/) JSON-API. -To enable the integration go to **Configuration** -> **Integrations** +Instructions on how to activate the API and if your model is supported can be found [here](http://jointspace.sourceforge.net/download.html). Note that not all listed, jointSPACE-enabled devices will have JSON-interface running on port 1925. This is true at least for some models before year 2011. + +{% include integrations/config_flow.md %} + +### Features + +| Feature | 1 | 5 | 6 (Android) | 6 (Saphi) | +| ------------------ | ---------------- | --- | ------------------ | ---------------- | +| Power On | WOL / IR Blaster | ? | Yes (if always on) | WOL / IR Blaster | +| Volume Detect | Yes | ? | Yes (not over CEC) | ? | +| Volume Up/Down | Yes | ? | Yes | No | +| Volume Set | Yes | ? | Yes | ? | +| Source Select | Yes | ? | Yes | No | +| Source Detect | Yes | ? | No | No | +| Channel Select | Yes | ? | Yes | ? | +| Channel Detect | Yes | ? | Yes | ? | +| Channel Favorites | No | ? | Yes | ? | +| Application Select | No | ? | Yes | No | +| Application Detect | No | ? | Yes | No | +| Browse URL | No | No | No | No | +| Send Key | No | No | No | No | +| Ambilight Control | No | No | No | No | ### Turn on device -The Philips TV does not support turning on via the API. You can either turn it on via IR blaster to or on som models WOL. To trigger this command from the entities, the integration exposes a `device trigger` that can be setup to execute when the `media_player` is asked to turn on. +The Philips TV does not always support turning on via the API. You can either turn it on via IR blaster or on som models WOL. To trigger this command from the entities, the integration exposes a `device trigger` that can be setup to execute when the `media_player` is asked to turn on. From ca9524323013df340408167f2bbe014f8fc2e5dc Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 1 Mar 2021 08:27:15 -0600 Subject: [PATCH 09/90] Remove griddy integration (#16790) --- source/_integrations/griddy.markdown | 53 ---------------------------- source/_redirects | 1 + 2 files changed, 1 insertion(+), 53 deletions(-) delete mode 100644 source/_integrations/griddy.markdown diff --git a/source/_integrations/griddy.markdown b/source/_integrations/griddy.markdown deleted file mode 100644 index 2823de39722..00000000000 --- a/source/_integrations/griddy.markdown +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Griddy Power -description: Instructions on how to integrate griddy real-time electricity prices into Home Assistant. -ha_category: - - Energy - - Sensor -ha_release: 0.107 -ha_iot_class: Cloud Polling -ha_config_flow: true -ha_codeowners: - - '@bdraco' -ha_domain: griddy -ha_platforms: - - sensor ---- - -The `griddy` integration allows you to integrate your [Griddy](https://griddy.com/) price data into Home Assistant. - -There is currently support for the following device types within Home Assistant: - -- Sensor - -## Prerequisites - -You will need your Griddy Load Zone to use this module. - -{% include integrations/config_flow.md %} - -### Sensor - -The current price for the Load Zone will appear as a sensor: - -- LZ_XXXXX Price Now - -### Example Automation - -```yaml -- id: '1572630019168' - alias: "Stop Tesla Charging if Power Price Spikes" - description: "" - trigger: - - above: '30' - entity_id: sensor.lz_houston_price_now - platform: numeric_state - condition: - - condition: zone - entity_id: device_tracker.my_tesla - zone: zone.home - action: - - service: switch.turn_off - target: - entity_id: switch.my_tesla_charger_switch -``` diff --git a/source/_redirects b/source/_redirects index f4bc0b59b4a..22d4f185a06 100644 --- a/source/_redirects +++ b/source/_redirects @@ -2285,3 +2285,4 @@ /components/sensor.coinmarketcap /more-info/removed-integration 301 /components/coinmarketcap /more-info/removed-integration 301 /integrations/coinmarketcap /more-info/removed-integration 301 +/integrations/griddy /more-info/removed-integration 301 From 0ad4b123275cc477010cb7288755059987d8b5cc Mon Sep 17 00:00:00 2001 From: Anders Melchiorsen Date: Mon, 1 Mar 2021 20:08:14 +0100 Subject: [PATCH 10/90] Clarify template trigger behaviour (#16733) --- source/_docs/automation/trigger.markdown | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/_docs/automation/trigger.markdown b/source/_docs/automation/trigger.markdown index d4642e31cd1..55ee1a5d69d 100644 --- a/source/_docs/automation/trigger.markdown +++ b/source/_docs/automation/trigger.markdown @@ -465,8 +465,11 @@ automation: ### Template trigger -Template triggers work by evaluating a [template](/docs/configuration/templating/) on every state change for all of the recognized entities. The trigger will fire if the state change caused the template to render 'true'. This is achieved by having the template result in a true boolean expression (`{% raw %}{{ is_state('device_tracker.paulus', 'home') }}{% endraw %}`) or by having the template render 'true' (example below). Being a boolean expression the template must evaluate to false (or anything other than true) before the trigger will fire again. -With template triggers you can also evaluate attribute changes by using is_state_attr (`{% raw %}{{ is_state_attr('climate.living_room', 'away_mode', 'off') }}{% endraw %}`) +Template triggers work by evaluating a [template](/docs/configuration/templating/) when any of the recognized entities change state. The trigger will fire if the state change caused the template to render 'true' (a non-zero number or any of the strings `true`, `yes`, `on`, `enable`) when it was previously 'false' (anything else). + +This is achieved by having the template result in a true boolean expression (for example `{% raw %}{{ is_state('device_tracker.paulus', 'home') }}{% endraw %}`) or by having the template render `true` (example below). + +With template triggers you can also evaluate attribute changes by using is_state_attr (like `{% raw %}{{ is_state_attr('climate.living_room', 'away_mode', 'off') }}{% endraw %}`) {% raw %} @@ -497,9 +500,9 @@ automation: {% endraw %} -The `for` template(s) will be evaluated when the `value_template` becomes `true`. +The `for` template(s) will be evaluated when the `value_template` becomes 'true'. -Templates that don't contain an entity will be rendered once per minute. +Templates that do not contain an entity will be rendered once per minute. ### Time trigger From 0148f5a3c12cb91aa5ac6d60eed12b642750980f Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 2 Mar 2021 05:17:36 -0500 Subject: [PATCH 11/90] Update Z-Wave JS limitations for next release (#16796) --- source/_integrations/zwave_js.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/_integrations/zwave_js.markdown b/source/_integrations/zwave_js.markdown index f5ecc35cdd6..70d4d8e72ed 100644 --- a/source/_integrations/zwave_js.markdown +++ b/source/_integrations/zwave_js.markdown @@ -103,6 +103,7 @@ data: parameter: "LED 1 Blink Status (bottom)" value: "Blink" ``` + ### Service `zwave_js.refresh_value` This service will refresh the value(s) for an entity. This service will generate extra traffic on your Z-Wave network and should be used sparingly. Updates from devices on battery may take some time to be received. @@ -181,8 +182,7 @@ Value Notification example: As this integration is still in the early stages there are some important limitations to be aware of. - While support for the most common devices is working, some command classes are not yet (fully) implemented in Z-Wave JS. You can track the status [here](https://github.com/zwave-js/node-zwave-js/issues/6). -- Configuration of Z-Wave nodes and/or configuration with the Home Assistant UI is currently not yet implemented. You will need to use another tool, such as [zwavejs2mqtt](https://github.com/zwave-js/zwavejs2mqtt), to manage device configuration. -- Polling is currently not supported in the integration but will be added soon as a service. +- Configuration of Z-Wave nodes within the Home Assistant UI is not yet implemented, but a [service](#service-zwave_js.set_config_parameter) is available with limited configuration capabilities. If the service doesn't meet your needs, you will need to use another tool, such as [zwavejs2mqtt](https://github.com/zwave-js/zwavejs2mqtt), to manage device configuration. - There currently is no migration path available from any of the other Z-Wave implementations in Home Assistant. Your Z-Wave network is however stored on your stick so migrating will only require you to redo your device and entity naming. You can keep track of the Roadmap for the Z-Wave JS integration [here](https://github.com/home-assistant-libs/zwave-js-server-python/issues/56). From 9efbce26f77af179eb12956ab84c226205b93c04 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 2 Mar 2021 14:13:56 +0100 Subject: [PATCH 12/90] My plugin updates (#16806) Co-authored-by: Bram Kragten --- .textlintrc.json | 3 +- plugins/my.rb | 46 +++++++++++++++++-- sass/custom/_paulus.scss | 1 - source/_docs/automation/services.markdown | 10 ++-- source/_docs/automation/templating.markdown | 2 +- .../automation/using_blueprints.markdown | 6 +-- .../asides/component_navigation.html | 2 +- source/_includes/common-tasks/snapshots.md | 18 +++----- source/_includes/integrations/config_flow.md | 4 +- 9 files changed, 61 insertions(+), 31 deletions(-) diff --git a/.textlintrc.json b/.textlintrc.json index 67f435bca75..aaf0c0dcc69 100644 --- a/.textlintrc.json +++ b/.textlintrc.json @@ -173,6 +173,7 @@ "MJPEG", "MQTT", "Mullvad", + "My Home Assistant", "MySensors", "NAS", "NETGEAR", @@ -278,7 +279,6 @@ "XML", "Yamaha MusicCast", "Yamaha", - "YAML", "Yandex", "Yeelight", "YouTube", @@ -302,7 +302,6 @@ ["cancelled", "canceled"], ["client ?side", "client-side"], ["colour", "color"], - ["config\\b", "configuration"], ["DarkSky", "Dark Sky"], ["docs\\b", "documentation"], ["e\\.g\\.", "e.g.,"], diff --git a/plugins/my.rb b/plugins/my.rb index 948e7efaf06..b785fb737f1 100644 --- a/plugins/my.rb +++ b/plugins/my.rb @@ -12,11 +12,11 @@ module Jekyll else raise SyntaxError, <<~MSG Syntax error in tag 'my' while parsing the following options: - ` + #{args} Valid syntax: - {% my [title="Link name"] [badge] [icon[="icon-puzzle-piece"]] [addon="core_ssh"] [blueprint_url=""] [domain="hue"] %} + {% my [title="Link name"] [badge] [icon[="icon-puzzle-piece"]] [addon="core_ssh"] [blueprint_url="http://example.com/blueprint.yaml"] [domain="hue"] [service="light.turn_on"] %} MSG end end @@ -33,24 +33,39 @@ module Jekyll query += [["addon", options[:addon]]] if options.include? :addon query += [["blueprint_url", options[:blueprint_url]]] if options.include? :blueprint_url query += [["domain", options[:domain]]] if options.include? :domain + query += [["service", options[:service]]] if options.include? :service unless query.empty? uri.query = URI.encode_www_form(query) end if options[:badge] - title = options[:title] ? options[:title].gsub(/\ /, '_') : @redirect + raise ArgumentError, "Badges cannot have custom titles" if options[:title] ""\ - ""\ + ""\ "" else - title = options[:title] ? options[:title] : @redirect.gsub(/_/, ' ').titlecase + title = @redirect.gsub(/_/, ' ').titlecase icon = "" + + if options[:title] + # Custom title + title = options[:title] + elsif @redirect == "developer_call_service" + # Developer service call + title = "Call Service" + title = "`#{options[:service]}`" if options.include? :service + elsif DEFAULT_TITLES.include?(@redirect) + # Lookup defaults + title = DEFAULT_TITLES[@redirect] + end + if options[:icon] raise ArgumentError, "No default icon for redirect #{@redirect}" \ if !!options[:icon] == options[:icon] and ! DEFAULT_ICONS.include?(@redirect) icon = !!options[:icon] == options[:icon] ? DEFAULT_ICONS[@redirect] : @options[:icon] icon = " " end + "#{icon}#{title}" end end @@ -60,11 +75,32 @@ module Jekyll SYNTAX = %r!^([a-z_]+)((\s+\w+(=([\w\.]+?|".+?"))?)*)$!.freeze OPTIONS_REGEX = %r!(?:\w="[^"]*"|\w=[\w\.]+|\w)+!.freeze + # Default icons when used in in-line text DEFAULT_ICONS = { "config_flow_start" => "icon-plus-sign", + "config" => "icon-cog", "integrations" => "icon-puzzle-piece", } + # Default title used for in-line text + DEFAULT_TITLES = { + "blueprint_import" => "Import Blueprint", + "cloud" => "Home Assistant Cloud", + "config_flow_start" => "Add Integration", + "config_mqtt" => "MQTT Configuration", + "config_zha" => "ZHA Configuration", + "config_zwave_js" => "Z-Wave JS Configuration", + "config" => "Configuration", + "developer_events" => "Events", + "developer_services" => "Services", + "developer_states" => "States", + "developer_template" => "Templates", + "general" => "General Settings", + "info" => "Information", + "supervisor_info" => "Supervisor Information", + "supervisor_snapshots" => "Snapshots", + } + def parse_options(input, context) options = {} return options if input.empty? diff --git a/sass/custom/_paulus.scss b/sass/custom/_paulus.scss index e313c289ff9..2dba14063b2 100644 --- a/sass/custom/_paulus.scss +++ b/sass/custom/_paulus.scss @@ -676,6 +676,5 @@ code { a.my { img { border: 0px; - border-radius: 3px; } } diff --git a/source/_docs/automation/services.markdown b/source/_docs/automation/services.markdown index 57525889bde..40e9ceaf90d 100644 --- a/source/_docs/automation/services.markdown +++ b/source/_docs/automation/services.markdown @@ -5,7 +5,7 @@ description: "How to use the various automation services." The automation integration has services to control automations, like turning automations on and off. This can be useful if you want to disable an automation from another automation. -## Service `automation.turn_on` +## Service {% my developer_call_service service="automation.turn_on" %} This service enables the automation's triggers. @@ -13,7 +13,7 @@ Service data attribute | Optional | Description -|-|- `entity_id` | no | Entity ID of automation to turn on. Can be a list. `none` or `all` are also accepted. -## Service `automation.turn_off` +## Service {% my developer_call_service service="automation.turn_off" %} This service disables the automation's triggers, and optionally stops any currently active actions. @@ -22,7 +22,7 @@ Service data attribute | Optional | Description `entity_id` | no | Entity ID of automation to turn on. Can be a list. `none` or `all` are also accepted. `stop_actions` | yes | Stop any currently active actions (defaults to true). -## Service `automation.toggle` +## Service {% my developer_call_service service="automation.toggle" %} This service enables the automation's triggers if they were disabled, or disables the automation's triggers, and stops any currently active actions, if the triggers were enabled. @@ -30,7 +30,7 @@ Service data attribute | Optional | Description -|-|- `entity_id` | no | Entity ID of automation to turn on. Can be a list. `none` or `all` are also accepted. -## Service `automation.trigger` +## Service {% my developer_call_service service="automation.trigger" %} This service will trigger the action of an automation. By default it bypasses any conditions, though that can be changed via the `skip_condition` attribute. @@ -39,7 +39,7 @@ Service data attribute | Optional | Description `entity_id` | no | Entity ID of automation to trigger. Can be a list. `none` or `all` are also accepted. `skip_condition` | yes | Whether or not the condition will be skipped (defaults to true). -## Service `automation.reload` +## Service {% my developer_call_service service="automation.reload" %} _This service is only required if you create/edit automations in YAML. Automations via the UI do this automatically._ diff --git a/source/_docs/automation/templating.markdown b/source/_docs/automation/templating.markdown index 15baca1e931..0b72cd1e459 100644 --- a/source/_docs/automation/templating.markdown +++ b/source/_docs/automation/templating.markdown @@ -7,7 +7,7 @@ Automations support [templating](/docs/configuration/templating/) in the same wa
    - Be aware that if you reference a `trigger` state object in templates of an automation' `action` or `condition` sections, attempting to test that automation by calling the `automation.trigger` service or by clicking EXECUTE in the More Info box for the automation will not work. This is because the trigger state object doesn't exist in those contexts. One way to test automations like these is to manually check that the templates work as expected by pasting them in Developer Tools > Template together with your trigger's definition like: + Be aware that if you reference a `trigger` state object in templates of an automation' `action` or `condition` sections, attempting to test that automation by calling the `automation.trigger` service or by clicking EXECUTE in the More Info box for the automation will not work. This is because the trigger state object doesn't exist in those contexts. One way to test automations like these is to manually check that the templates work as expected by pasting them in {% my developer_template title="Developer Tools > Template" %} together with your trigger's definition like: {%raw%} diff --git a/source/_docs/automation/using_blueprints.markdown b/source/_docs/automation/using_blueprints.markdown index 5f10a2d25a1..a17617bacd1 100644 --- a/source/_docs/automation/using_blueprints.markdown +++ b/source/_docs/automation/using_blueprints.markdown @@ -13,11 +13,11 @@ Quick links: Automations based on a blueprint only need to be configured to be used. What needs to be configured differs on each blueprint. -To create your first automation based on a blueprint, go to **Configuration** and then **Blueprints**. Find the blueprint that you want to use and click on "Create Automation". +To create your first automation based on a blueprint, go to **{% my config %}** and then **{% my blueprints %}**. Find the blueprint that you want to use and click on "Create Automation". This will open the automation editor with the blueprint selected. Give it a name and configure the blueprint and click on the blue button "Save Automation" in the bottom right. -Done! If you want to revisit the configuration values, you can find it by going to **Configuration** and then **Automations**. +Done! If you want to revisit the configuration values, you can find it by going to **{% my config %}** and then **{% my automations %}**. ## Importing blueprints @@ -29,7 +29,7 @@ To do this, first [find a blueprint you want to import][blueprint-forums]. If yo https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/motion_light.yaml ``` -Go to **Configuration** and then **Blueprints**. Click on the blue "Import Blueprint" button in the bottom right. +Go to **{% my config %}** and then **{% my blueprints %}**. Click on the blue "{% my blueprint_import blueprint="https://github.com/home-assistant/core/blob/master/homeassistant/components/automation/blueprints/motion_light.yaml" %} button in the bottom right. A new dialog will pop-up asking you for the URL. Enter the URL and click on "preview blueprint". diff --git a/source/_includes/asides/component_navigation.html b/source/_includes/asides/component_navigation.html index e93dfc2c5a9..75a809b5399 100644 --- a/source/_includes/asides/component_navigation.html +++ b/source/_includes/asides/component_navigation.html @@ -8,7 +8,7 @@ {%- endif -%} {%- if page.ha_config_flow and page.ha_domain -%} - {% my config_flow_start badge title="Add Integration" domain=page.ha_domain %} + {% my config_flow_start badge domain=page.ha_domain %} {%- endif -%}
    diff --git a/source/_includes/common-tasks/snapshots.md b/source/_includes/common-tasks/snapshots.md index b806173f345..49f33abd950 100644 --- a/source/_includes/common-tasks/snapshots.md +++ b/source/_includes/common-tasks/snapshots.md @@ -14,7 +14,7 @@ A partial snapshot consists of any number of the above default directories and i ### Making a Snapshot from the UI -1. Go to Supervisor > Snapshots in the UI +1. Go to {% my supervisor_snapshots title="Supervisor > Snapshots" %} in the UI 2. Provide a name for the snapshot. 3. Choose full or partial. 4. Choose to password protect or not. Password protected snapshots cannot easily be browsed outside of Home Assistant OS @@ -33,7 +33,7 @@ When the upload is completed, you will be presented with the snapshot restore di If the snapshot you are uploading is more than 1GB in size, it can be faster and more efficient to make use of the Samba add-on in order to transfer files to the `/backup` directory. -The length of time it takes to create or restore snapshots will depend on how much you have to compress or decompress. +The length of time it takes to create or restore snapshots will depend on how much you have to compress or decompress. If you're looking to slim down your snapshots, check if your configuration directory contains a large database file (`home-assistant_v2.db`). See the [`recorder`](https://www.home-assistant.io/components/recorder/) integration page for options to keep your database data down to a size that won't cause issues. Note the keep days, purge interval, and include/exclude options. @@ -52,12 +52,8 @@ Use `ha help` to see more info. You often need a snapshot in case your system has crashed. If you only store them on the crashed device, you won't be able to access it easily. We recommend that you manually copy them from `/backup` to another machine on occasion. Or even better, create an automation to handle that, or make use of one of the following add-ons: - - [Google Drive Backup](https://github.com/sabeechen/hassio-google-drive-backup) - - - [Dropbox Sync](https://github.com/danielwelch/hassio-dropbox-sync) - - - [Nextcloud Backup](https://github.com/Sebclem/hassio-nextcloud-backup) - - - [Samba backup](https://github.com/thomasmauerer/hassio-addons/tree/master/samba-backup) - - - [Remote Backup (uses scp)](https://github.com/overkill32/hassio-remote-backup) \ No newline at end of file +- [Google Drive Backup](https://github.com/sabeechen/hassio-google-drive-backup) +- [Dropbox Sync](https://github.com/danielwelch/hassio-dropbox-sync) +- [Nextcloud Backup](https://github.com/Sebclem/hassio-nextcloud-backup) +- [Samba backup](https://github.com/thomasmauerer/hassio-addons/tree/master/samba-backup) +- [Remote Backup (uses scp)](https://github.com/overkill32/hassio-remote-backup) diff --git a/source/_includes/integrations/config_flow.md b/source/_includes/integrations/config_flow.md index ff49aa3acb3..20c04db3e1a 100644 --- a/source/_includes/integrations/config_flow.md +++ b/source/_includes/integrations/config_flow.md @@ -6,7 +6,7 @@ Adding {{ name }} to your Home Assistant instance can be done via the user interface, by taking the following steps: - Browse to your Home Assistant instance. -- In the sidebar click on _**Configuration**_. +- In the sidebar click on _**{% my config icon %}**_. - From the configuration menu select: _**{% my integrations icon %}**_. {% if include.discovery or page.ha_dhcp or page.ha_homekit or page.ha_ssdp or page.ha_zeroconf %} @@ -20,7 +20,7 @@ manual integration entry: {% endif %} - In the bottom right, click on the - _**{% my config_flow_start icon title="Add Integration" domain=page.ha_domain %}**_ button. + _**{% my config_flow_start icon domain=page.ha_domain %}**_ button. - From the list, search and select _**"{{ name }}"**_. - Follow the instruction on screen to complete the set up. From f467f4929b6d1ed2617000206c236051fdbf2798 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 2 Mar 2021 21:14:00 +0100 Subject: [PATCH 13/90] Add more My links (#16816) --- source/_docs/authentication/multi-factor-auth.markdown | 6 +++--- source/_docs/authentication/providers.markdown | 2 +- source/_docs/automation/basics.markdown | 4 ++-- source/_docs/automation/editor.markdown | 5 +++-- source/_docs/automation/troubleshooting.markdown | 4 ++-- source/_docs/automation/yaml.markdown | 2 +- source/_docs/blueprint/tutorial.markdown | 2 +- source/_docs/configuration/basic.markdown | 2 +- source/_docs/configuration/devices.markdown | 2 +- source/_docs/configuration/splitting_configuration.markdown | 2 +- source/_docs/configuration/templating.markdown | 2 +- source/_integrations/xbox.markdown | 2 +- source/_integrations/zwave_js.markdown | 2 +- 13 files changed, 19 insertions(+), 18 deletions(-) diff --git a/source/_docs/authentication/multi-factor-auth.markdown b/source/_docs/authentication/multi-factor-auth.markdown index 47969af1dee..d295b48b4be 100644 --- a/source/_docs/authentication/multi-factor-auth.markdown +++ b/source/_docs/authentication/multi-factor-auth.markdown @@ -36,9 +36,9 @@ If no `auth_mfa_modules` configuration section is defined in `configuration.yaml You will need an authenticator app on your phone. We recommend either [Google Authenticator](https://support.google.com/accounts/answer/1066447) or [Authy](https://authy.com/). Both are available for iOS or Android. -After restarting Home Assistant, go to your [profile page](/docs/authentication/#your-account-profile) and there should be a "Multi-factor Authentication Modules" section. +After restarting Home Assistant, go to your {% my profile %} and there should be a "Multi-factor Authentication Modules" section. -Click _Enable_ and a new secret key will be generated. Go to your phone app and enter the key, either by scanning the QR code or typing in the key below the QR code manually. +Click _Enable_ and a new secret key will be generated. Go to your phone app and enter the key, either by scanning the QR code or typing in the key below the QR code manually. Screenshot of setting up multi-factor authentication @@ -99,7 +99,7 @@ homeassistant: message: "I almost forget, to get into my clubhouse, you need to say {}" ``` -After restarting Home Assistant, go to your [profile page](/docs/authentication/#your-account-profile) and there should be a "Multi-factor Authentication Modules" section. Click _Enable_ on the _Notify One-Time Password_ option. +After restarting Home Assistant, go to your {% my profile %} and there should be a "Multi-factor Authentication Modules" section. Click _Enable_ on the _Notify One-Time Password_ option. Try logging out, then logging in again. You will be asked for the six-digit one-time password that was sent to your notify service. Enter the password to log in. diff --git a/source/_docs/authentication/providers.markdown b/source/_docs/authentication/providers.markdown index a8003727e37..c414de45e3f 100644 --- a/source/_docs/authentication/providers.markdown +++ b/source/_docs/authentication/providers.markdown @@ -37,7 +37,7 @@ This is the default auth provider. The first user created is designated as the _ User details are stored in the `[your config]/.storage` directory. All passwords are stored hashed and with a salt, making it almost impossible for an attacker to figure out the password even if they have access to the file. -Users can be managed in Home Assistant by the owner. Go to the configuration panel and click on _Users_. +Users can be managed in Home Assistant by the owner. Go to the configuration panel and click on _{% my users %}_. This is the entry in `configuration.yaml` for Home Assistant auth: diff --git a/source/_docs/automation/basics.markdown b/source/_docs/automation/basics.markdown index fb46acb9a40..87a1d384f25 100644 --- a/source/_docs/automation/basics.markdown +++ b/source/_docs/automation/basics.markdown @@ -27,7 +27,7 @@ The difference between a condition and a trigger can be confusing as they are ve ## Exploring the internal state -Automation rules interact directly with the internal state of Home Assistant, so you'll need to familiarize yourself with it. Home Assistant exposes its current state via the developer tools. These are available at the bottom of the sidebar in the frontend. **Developer Tools** -> **States** will show all currently available states. An entity can be anything. A light, a switch, a person and even the sun. A state consists of the following parts: +Automation rules interact directly with the internal state of Home Assistant, so you'll need to familiarize yourself with it. Home Assistant exposes its current state via the developer tools. These are available at the bottom of the sidebar in the frontend. **{% my developer_states title="Developer Tools -> States" %}** will show all currently available states. An entity can be anything. A light, a switch, a person and even the sun. A state consists of the following parts: | Name | Description | Example | | ---- | ----- | ---- | @@ -37,7 +37,7 @@ Automation rules interact directly with the internal state of Home Assistant, so State changes can be used as the source of triggers and the current state can be used in conditions. -Actions are all about calling services. To explore the available services open the **Developer Tools** -> **Services**. Services allow changing anything. For example turn on a light, run a script or enable a scene. Each service has a domain and a name. For example the service `light.turn_on` is capable of turning on any light in your system. Services can be passed parameters to for example tell which device to turn on or what color to use. +Actions are all about calling services. To explore the available services open the **{% my developer_states title="Developer Tools -> Services" %}**. Services allow changing anything. For example turn on a light, run a script or enable a scene. Each service has a domain and a name. For example the service {% my developer_call_service service="light.turn_on" %} is capable of turning on any light in your system. Services can be passed parameters to for example tell which device to turn on or what color to use. ## Creating automations diff --git a/source/_docs/automation/editor.markdown b/source/_docs/automation/editor.markdown index 4e51eee8d1c..a4f8cab57a0 100644 --- a/source/_docs/automation/editor.markdown +++ b/source/_docs/automation/editor.markdown @@ -3,7 +3,7 @@ title: "Automation Editor" description: "Instructions on how to use the automation editor." --- -From the UI choose **Configuration** which is located in the sidebar, then click on **Automation** to go to the automation editor. Press the **+** sign in the lower right corner to get started. This example is based on the manual steps described in the [Getting started section](/getting-started/automation/) for a [`random` sensor](/integrations/random#sensor). +From the UI choose **{% my config %}** which is located in the sidebar, then click on **{% my automations %}** to go to the automation editor. Press the **+** sign in the lower right corner to get started. This example is based on the manual steps described in the [Getting started section](/getting-started/automation/) for a [`random` sensor](/integrations/random#sensor). Choose a meaningful name for your automation rules. @@ -29,4 +29,5 @@ As "Service Data" we want a simple text that is shown as part of the notificatio message: Sensor value greater than 10 ``` -Don't forget to save your new automation rule. For your saved automation rule to come into effect, you will need to go to the **Configuration** page and click on **Reload Automation**. +Automation created or edited via the user interface, are activated immediately +after save the automation. diff --git a/source/_docs/automation/troubleshooting.markdown b/source/_docs/automation/troubleshooting.markdown index 1181dbb4b60..f63899cf928 100644 --- a/source/_docs/automation/troubleshooting.markdown +++ b/source/_docs/automation/troubleshooting.markdown @@ -27,11 +27,11 @@ Please note that if you click on **Trigger** of an automation in the frontend, * All this makes that Trigger feature pretty limited and nearly useless for debugging purposes so you need to find another way. Make sure you check and adapt to your circumstances appropriate examples from Automation Trigger, Conditions and Actions. -It is also useful to go to **Configuration** -> **Server Control** and click on **Check Configuration** button in Configuration validation section to make sure there are no syntax errors before restarting Home Assistant. In order for **Check configuration** to be visible, you must enable **Advanced Mode** on your user profile. +It is also useful to go to **{% my server_controls title="Configuration -> Server Control" %}** and click on **Check Configuration** button in Configuration validation section to make sure there are no syntax errors before restarting Home Assistant. In order for **Check configuration** to be visible, you must enable **Advanced Mode** on {% my profile title="your user profile" %}. If your automation uses templates in any part, you can do the following to make sure it works as expected: -1. Go to **Developer tools** -> **Template** tab. +1. Go to **{% my developer_templates title="Developer tools -> Template" %}** tab. 2. Create all variables (sources) required for your template as described at the end of [this](https://www.home-assistant.io/docs/configuration/templating/#processing-incoming-data) paragraph. 3. Copy your template code and paste it in Template editor straight after your variables. 4. If necessary, change your sources' value and check if the template works as you want and does not generate any errors. diff --git a/source/_docs/automation/yaml.markdown b/source/_docs/automation/yaml.markdown index 2efe894ad7e..77a869289f0 100644 --- a/source/_docs/automation/yaml.markdown +++ b/source/_docs/automation/yaml.markdown @@ -148,6 +148,6 @@ If you want to migrate your manual automations to use the editor, you'll have to When automations remain visible in the Home Assistant Dashboard, even after having deleted in the YAML file, you have to delete them in the UI. -To delete them completely, go to UI **Configuration** -> **Entities** and find the automation in the search field or by scrolling down. +To delete them completely, go to UI **{% my entities title="Configuration -> Entities" %}** and find the automation in the search field or by scrolling down. Check the square box aside of the automation you wish to delete and from the top-right of your screen, select 'REMOVE SELECTED'. diff --git a/source/_docs/blueprint/tutorial.markdown b/source/_docs/blueprint/tutorial.markdown index ec95e596db2..d26eaa99bed 100644 --- a/source/_docs/blueprint/tutorial.markdown +++ b/source/_docs/blueprint/tutorial.markdown @@ -208,7 +208,7 @@ action: ## Use it via the UI -To configure it via the UI, go to **Configuration** and then **Blueprints**. Find the "Motion Light Tutorial" blueprint and click on "Create Automation". +To configure it via the UI, go to **{% my config %}** and then **{% my blueprints %}**. Find the "Motion Light Tutorial" blueprint and click on "Create Automation".
    Don't forget to reload automations after you make changes to your blueprint to have the UI and the automation integration pick up the latest blueprint changes. diff --git a/source/_docs/configuration/basic.markdown b/source/_docs/configuration/basic.markdown index 0742a6bd824..d1d5396947d 100644 --- a/source/_docs/configuration/basic.markdown +++ b/source/_docs/configuration/basic.markdown @@ -100,4 +100,4 @@ legacy_templates: ## Reload Core Service -Home Assistant offers a service to reload the core configuration while Home Assistant is running called `homeassistant.reload_core_config`. This allows you to change any of the above sections and see it being applied without having to restart Home Assistant. To call this service, go to the "Service" tab under Developer Tools, select the `homeassistant.reload_core_config` service and click the "CALL SERVICE" button. Alternatively, you can press the "Reload Location & Customizations" button under Configuration > Server Control. +Home Assistant offers a service to reload the core configuration while Home Assistant is running called {% my developer_call_service service="homeassistant.reload_core_config" %}. This allows you to change any of the above sections and see it being applied without having to restart Home Assistant. To call this service, go to the "{% my developer_services %}" tab under {% my developer_services title="Developer Tools" %}, select the {% my developer_call_service service="homeassistant.reload_core_config" %} service and click the "CALL SERVICE" button. Alternatively, you can press the "Reload Location & Customizations" button under {% my server_controls title="Configuration > Server Control" %}. diff --git a/source/_docs/configuration/devices.markdown b/source/_docs/configuration/devices.markdown index a170014870a..0f93b43382a 100644 --- a/source/_docs/configuration/devices.markdown +++ b/source/_docs/configuration/devices.markdown @@ -62,7 +62,7 @@ switch 2: ## Grouping devices Once you have several devices set up, it is time to organize them into groups. -Each group consists of a name and a list of entity IDs. Entity IDs can be retrieved from the web interface by using the “States” page in the Developer Tools. +Each group consists of a name and a list of entity IDs. Entity IDs can be retrieved from the web interface by using the {% my developer_states title="States page in the Developer Tools" %}. ```yaml # Example configuration.yaml entry showing two styles diff --git a/source/_docs/configuration/splitting_configuration.markdown b/source/_docs/configuration/splitting_configuration.markdown index 642048da29f..5bfbc9d3233 100644 --- a/source/_docs/configuration/splitting_configuration.markdown +++ b/source/_docs/configuration/splitting_configuration.markdown @@ -491,7 +491,7 @@ front_yard: ### Example: Combine `!include_dir_merge_list` with `automations.yaml` -You want to go the advanced route and split your automations, but still want to be able to create automations in the UI? +You want to go the advanced route and split your automations, but still want to be able to create {% my automations title="automations in the UI" %}? In a chapter above we write about nesting `!includes`. Here is how we can do that for automations. Using labels like `manual` or `ui` allows for using multiple keys in the config: diff --git a/source/_docs/configuration/templating.markdown b/source/_docs/configuration/templating.markdown index 15f2e1387a0..3f3852ffa3c 100644 --- a/source/_docs/configuration/templating.markdown +++ b/source/_docs/configuration/templating.markdown @@ -24,7 +24,7 @@ Templating in Home Assistant is powered by the [Jinja2](https://palletsprojects. We will not go over the basics of the syntax, as Jinja2 does a great job of this in their [templates documentation](https://jinja.palletsprojects.com/en/master/templates/). -The frontend has a template editor tool to help develop and debug templates. Navigate to Developer Tools > Template, create your template in the _Template editor_ and check the results on the right. +The frontend has a {% my developer_templates title="template editor tool" %} to help develop and debug templates. Navigate to {% my developer_templates title="Developer Tools > Template" %}, create your template in the _Template editor_ and check the results on the right. Templates can get big pretty fast. To keep a clear overview, consider using YAML multiline strings to define your templates: diff --git a/source/_integrations/xbox.markdown b/source/_integrations/xbox.markdown index 60176702b23..d5a1e614f4d 100644 --- a/source/_integrations/xbox.markdown +++ b/source/_integrations/xbox.markdown @@ -40,7 +40,7 @@ The Xbox media player platform will create Media Player entities for each consol Launches an application on the Xbox console using the application's product ID. Also supports "Home" and "TV" to navigate to the dashboard or Live TV respectively. -You can find Product IDs using the **Developer Tools -> Events** tab and listening to the `call_service` event. In a new browser tab, navigate to the media browser for your console and click on an App/Game to see the product ID in the event. +You can find Product IDs using the **{% my developer_events title="Developer Tools -> Events" %}** tab and listening to the `call_service` event. In a new browser tab, navigate to the media browser for your console and click on an App/Game to see the product ID in the event. | Service data attribute | Description | | ---------------------- | --------------------------------------| diff --git a/source/_integrations/zwave_js.markdown b/source/_integrations/zwave_js.markdown index 70d4d8e72ed..edd74a0d612 100644 --- a/source/_integrations/zwave_js.markdown +++ b/source/_integrations/zwave_js.markdown @@ -136,7 +136,7 @@ Valid code slots are between 1-254. ## Events -Events are fired when you press a button on a remote (aka Central Scene support) or when a stateless value is being signalled by a device. You can test what events come in using the event developer tools in Home Assistant and subscribe to `zwave_js_event`. Once you know what the event data looks like, you can use this to create automations. +Events are fired when you press a button on a remote (aka Central Scene support) or when a stateless value is being signalled by a device. You can test what events come in using the event {% my developer_events title="developer tools in Home Assistant" %} and subscribe to `zwave_js_event`. Once you know what the event data looks like, you can use this to create automations. ### Node events (Notification) From 1a49a1b18160e7a8d950b0fc3c8034f16e6d5858 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 2 Mar 2021 21:14:30 +0100 Subject: [PATCH 14/90] Collection of Markdown/YAML cleanups (#16817) --- .../authentication/multi-factor-auth.markdown | 2 +- source/_docs/automation/action.markdown | 31 +- source/_docs/automation/basics.markdown | 2 +- source/_docs/automation/condition.markdown | 30 +- source/_docs/automation/templating.markdown | 18 +- source/_docs/automation/trigger.markdown | 442 +++++++++--------- source/_docs/automation/yaml.markdown | 59 ++- source/_docs/blueprint/schema.markdown | 8 +- source/_docs/blueprint/tutorial.markdown | 18 +- source/_docs/configuration/basic.markdown | 10 +- source/_docs/configuration/devices.markdown | 10 +- source/_docs/configuration/packages.markdown | 9 +- .../configuration/platform_options.markdown | 4 +- source/_docs/configuration/remote.markdown | 4 - source/_docs/configuration/secrets.markdown | 2 +- .../splitting_configuration.markdown | 94 ++-- .../_docs/configuration/templating.markdown | 85 +++- .../configuration/troubleshooting.markdown | 2 +- source/_docs/configuration/yaml.markdown | 12 +- 19 files changed, 446 insertions(+), 396 deletions(-) diff --git a/source/_docs/authentication/multi-factor-auth.markdown b/source/_docs/authentication/multi-factor-auth.markdown index d295b48b4be..240224f0a83 100644 --- a/source/_docs/authentication/multi-factor-auth.markdown +++ b/source/_docs/authentication/multi-factor-auth.markdown @@ -94,7 +94,7 @@ message: homeassistant: auth_mfa_modules: - type: totp - name: Authenticator app + name: "Authenticator app" - type: notify message: "I almost forget, to get into my clubhouse, you need to say {}" ``` diff --git a/source/_docs/automation/action.markdown b/source/_docs/automation/action.markdown index 3297a6749ef..74ccbe6f9e7 100644 --- a/source/_docs/automation/action.markdown +++ b/source/_docs/automation/action.markdown @@ -11,23 +11,24 @@ You can also call the service to activate [a scene](/integrations/scene/) which automation: # Change the light in the kitchen and living room to 150 brightness and color red. trigger: - platform: sun - event: sunset + - platform: sun + event: sunset action: - service: light.turn_on - data: - brightness: 150 - rgb_color: [255, 0, 0] - entity_id: - - light.kitchen - - light.living_room + - service: light.turn_on + target: + entity_id: + - light.kitchen + - light.living_room + data: + brightness: 150 + rgb_color: [255, 0, 0] automation 2: # Notify me on my mobile phone of an event trigger: - platform: sun - event: sunset - offset: -00:30 + - platform: sun + event: sunset + offset: -00:30 variables: notification_service: notify.paulus_iphone action: @@ -47,9 +48,9 @@ Conditions can also be part of an action. You can combine multiple service calls automation: - alias: "Office at evening" trigger: - platform: state - entity_id: sensor.office_occupancy - to: "on" + - platform: state + entity_id: sensor.office_occupancy + to: "on" action: - service: notify.notify data: diff --git a/source/_docs/automation/basics.markdown b/source/_docs/automation/basics.markdown index 87a1d384f25..0ad584c5e5e 100644 --- a/source/_docs/automation/basics.markdown +++ b/source/_docs/automation/basics.markdown @@ -15,7 +15,7 @@ We can break up this automation into the following three parts: (action) Turn the lights on in the living room ``` -The first part is the [trigger](/docs/automation/trigger/) of the automation rule. Triggers describe events that should trigger the automation rule. In this case, it is a person arriving home, which can be observed in Home Assistant by observing the state of Paulus changing from 'not_home' to 'home'. +The first part is the [trigger](/docs/automation/trigger/) of the automation rule. Triggers describe events that should trigger the automation rule. In this case, it is a person arriving home, which can be observed in Home Assistant by observing the state of Paulus changing from `not_home` to `home`. The second part is the [condition](/docs/automation/condition/). Conditions are optional tests that can limit an automation rule to only work in your specific use cases. A condition will test against the current state of the system. This includes the current time, devices, people and other things like the sun. In this case, we only want to act when the sun has set. diff --git a/source/_docs/automation/condition.markdown b/source/_docs/automation/condition.markdown index b530f18e5de..d9f7076920d 100644 --- a/source/_docs/automation/condition.markdown +++ b/source/_docs/automation/condition.markdown @@ -15,19 +15,19 @@ Example of using condition: automation: - alias: "Enciende Despacho" trigger: - platform: state - entity_id: sensor.mini_despacho - to: "on" + - platform: state + entity_id: sensor.mini_despacho + to: "on" condition: - condition: or - conditions: - - condition: numeric_state - entity_id: sun.sun - attribute: elevation - below: 4 - - condition: numeric_state - entity_id: sensor.sensorluz_7_0 - below: 10 + - condition: or + conditions: + - condition: numeric_state + entity_id: sun.sun + attribute: elevation + below: 4 + - condition: numeric_state + entity_id: sensor.sensorluz_7_0 + below: 10 action: - service: scene.turn_on target: @@ -44,9 +44,9 @@ The `condition` option of an automation, also accepts a single condition templat automation: - alias: "Enciende Despacho" trigger: - platform: state - entity_id: sensor.mini_despacho - to: "on" + - platform: state + entity_id: sensor.mini_despacho + to: "on" condition: "{{ state_attr('sun.sun', 'elevation') < 4 }}" action: - service: scene.turn_on diff --git a/source/_docs/automation/templating.markdown b/source/_docs/automation/templating.markdown index 0b72cd1e459..38da81fa0bf 100644 --- a/source/_docs/automation/templating.markdown +++ b/source/_docs/automation/templating.markdown @@ -127,19 +127,19 @@ The following tables show the available trigger data per platform. # Example configuration.yaml entries automation: trigger: - platform: state - entity_id: device_tracker.paulus + - platform: state + entity_id: device_tracker.paulus action: - service: notify.notify - data: - message: > - Paulus just changed from {{ trigger.from_state.state }} - to {{ trigger.to_state.state }} + - service: notify.notify + data: + message: > + Paulus just changed from {{ trigger.from_state.state }} + to {{ trigger.to_state.state }} automation 2: trigger: - platform: mqtt - topic: /notify/+ + - platform: mqtt + topic: "/notify/+" action: service: > notify.{{ trigger.topic.split('/')[-1] }} diff --git a/source/_docs/automation/trigger.markdown b/source/_docs/automation/trigger.markdown index 55ee1a5d69d..8f8a730b958 100644 --- a/source/_docs/automation/trigger.markdown +++ b/source/_docs/automation/trigger.markdown @@ -3,7 +3,7 @@ title: "Automation Trigger" description: "All the different ways how automations can be triggered." --- -### What are triggers +## What are triggers Triggers are what starts the processing of an automation rule. When _any_ of the automation's triggers becomes true (trigger _fires_), Home Assistant will validate the [conditions](/docs/automation/condition/), if any, and call the [action](/docs/automation/action/). @@ -11,11 +11,11 @@ An automation can be triggered by an event, with a certain entity state, at a gi The following sections introduce all trigger types and further details to get started. -### Trigger variables +## Trigger variables Similar to [script level variables](/integrations/script/#variables), `trigger_variables` will be available in trigger templates with the difference that only [limited templates](/docs/configuration/templating/#limited-templates) can be used to pass a value to the trigger variable. -### Event trigger +## Event trigger Fires when an event is being received. Events are the raw building blocks of Home Assistant. You can match events on just the event name or also require specific event data or context to be present. @@ -24,16 +24,16 @@ Events can be fired by integrations or via the API. There is no limitation to th ```yaml automation: trigger: - platform: event - event_type: MY_CUSTOM_EVENT - # optional - event_data: - mood: happy - context: - user_id: - # any of these will match - - MY_USER_ID - - ANOTHER_USER_ID + - platform: event + event_type: "MY_CUSTOM_EVENT" + # optional + event_data: + mood: happy + context: + user_id: + # any of these will match + - "MY_USER_ID" + - "ANOTHER_USER_ID" ``` It is also possible to listen for multiple events at once. This is useful for @@ -42,10 +42,10 @@ event that contain no, or similar, data and contexts. ```yaml automation: trigger: - platform: event - event_type: - - automation_reloaded - - scene_reloaded + - platform: event + event_type: + - automation_reloaded + - scene_reloaded ``` It's also possible to use [limited templates](/docs/configuration/templating/#limited-templates) in the `event_type`, `event_data` and `context` options. @@ -65,36 +65,36 @@ automation: node: ac value: on trigger: - platform: event - event_type: "{{ 'MY_CUSTOM_EVENT_' ~ sub_event }}" + - platform: event + event_type: "{{ 'MY_CUSTOM_EVENT_' ~ sub_event }}" ``` {% endraw %} -### Home Assistant trigger +## Home Assistant trigger Fires when Home Assistant starts up or shuts down. ```yaml automation: trigger: - platform: homeassistant - # Event can also be 'shutdown' - event: start + - platform: homeassistant + # Event can also be 'shutdown' + event: start ``` -### MQTT trigger +## MQTT trigger Fires when a specific message is received on given MQTT topic. Optionally can match on the payload being sent over the topic. The default payload encoding is 'utf-8'. For images and other byte payloads use `encoding: ''` to disable payload decoding completely. ```yaml automation: trigger: - platform: mqtt - topic: living_room/switch/ac - # Optional - payload: "on" - encoding: "utf-8" + - platform: mqtt + topic: "living_room/switch/ac" + # Optional + payload: "on" + encoding: "utf-8" ``` The `payload` option can be combined with a `value_template` to process the message received on the given MQTT topic before matching it with the payload. @@ -105,10 +105,10 @@ The trigger in the example below will trigger only when the message received on ```yaml automation: trigger: - platform: mqtt - topic: "living_room/switch/ac" - payload: "on" - value_template: "{{ value_json.state }}" + - platform: mqtt + topic: "living_room/switch/ac" + payload: "on" + value_template: "{{ value_json.state }}" ``` {% endraw %} @@ -130,16 +130,16 @@ automation: node: "ac" value: "on" trigger: - platform: mqtt - topic: "{{ room ~ '/switch/' ~ node}}" - # Optional - payload: "{{ 'state:' ~ value }}" - encoding: "utf-8" + - platform: mqtt + topic: "{{ room ~ '/switch/' ~ node}}" + # Optional + payload: "{{ 'state:' ~ value }}" + encoding: "utf-8" ``` {% endraw %} -### Numeric state trigger +## Numeric state trigger Fires when the numeric value of an entity's state (or attribute's value if using the `attribute` property) crosses a given threshold. On state change of a specified entity, attempts to parse the state as a number and fires if the value is changing from above to below or from below to above the given threshold. @@ -148,20 +148,20 @@ Fires when the numeric value of an entity's state (or attribute's value if using ```yaml automation: trigger: - platform: numeric_state - entity_id: sensor.temperature - # Optional - value_template: "{{ state.attributes.battery }}" - # At least one of the following required - above: 17 - below: 25 - # If given, will trigger when the value of the given attribute for the given entity changes - attribute: attribute_name - # If given, will trigger when the condition has been true for X time; you can also use days and milliseconds. - for: - hours: 1 - minutes: 10 - seconds: 5 + - platform: numeric_state + entity_id: sensor.temperature + # Optional + value_template: "{{ state.attributes.battery }}" + # At least one of the following required + above: 17 + below: 25 + # If given, will trigger when the value of the given attribute for the given entity changes + attribute: attribute_name + # If given, will trigger when the condition has been true for X time; you can also use days and milliseconds. + for: + hours: 1 + minutes: 10 + seconds: 5 ``` {% endraw %} @@ -177,11 +177,11 @@ the trigger more dynamic, like: ```yaml automation: trigger: - platform: numeric_state - entity_id: sensor.temperature - # input_number entity id can be specified for above and/or below thresholds - above: input_number.temperature_threshold_high - below: input_number.temperature_threshold_low + - platform: numeric_state + entity_id: sensor.temperature + # input_number entity id can be specified for above and/or below thresholds + above: input_number.temperature_threshold_high + below: input_number.temperature_threshold_low ``` The `for:` can also be specified as `HH:MM:SS` like this: @@ -191,16 +191,16 @@ The `for:` can also be specified as `HH:MM:SS` like this: ```yaml automation: trigger: - platform: numeric_state - entity_id: sensor.temperature - # Optional - value_template: "{{ state.attributes.battery }}" - # At least one of the following required - above: 17 - below: 25 + - platform: numeric_state + entity_id: sensor.temperature + # Optional + value_template: "{{ state.attributes.battery }}" + # At least one of the following required + above: 17 + below: 25 - # If given, will trigger when condition has been for X time. - for: "01:10:05" + # If given, will trigger when condition has been for X time. + for: "01:10:05" ``` {% endraw %} @@ -212,26 +212,26 @@ You can also use templates in the `for` option. ```yaml automation: trigger: - platform: numeric_state - entity_id: - - sensor.temperature_1 - - sensor.temperature_2 - above: 80 - for: - minutes: "{{ states('input_number.high_temp_min')|int }}" - seconds: "{{ states('input_number.high_temp_sec')|int }}" + - platform: numeric_state + entity_id: + - sensor.temperature_1 + - sensor.temperature_2 + above: 80 + for: + minutes: "{{ states('input_number.high_temp_min')|int }}" + seconds: "{{ states('input_number.high_temp_sec')|int }}" action: - service: persistent_notification.create - data: - message: > - {{ trigger.to_state.name }} too high for {{ trigger.for }}! + - service: persistent_notification.create + data: + message: > + {{ trigger.to_state.name }} too high for {{ trigger.for }}! ``` {% endraw %} The `for` template(s) will be evaluated when an entity changes as specified. -### State trigger +## State trigger Fires when the state of any of given entities changes. If only `entity_id` is given, the trigger will fire for all state changes, even if only state attributes change. If only one of `from_state` or `to_state` are given, the trigger will fire on any matching state change, but not if only attributes change. @@ -245,14 +245,14 @@ The values you see in your overview will often not be the same as the actual sta ```yaml automation: trigger: - platform: state - entity_id: - - device_tracker.paulus - - device_tracker.anne_therese - # Optional - from: "not_home" - # Optional - to: "home" + - platform: state + entity_id: + - device_tracker.paulus + - device_tracker.anne_therese + # Optional + from: "not_home" + # Optional + to: "home" ``` It's possible to give a list of from_states or to_states: @@ -260,15 +260,15 @@ It's possible to give a list of from_states or to_states: ```yaml automation: trigger: - platform: state - entity_id: vacuum.test - from: - - "cleaning" - - "returning" - to: "error" + - platform: state + entity_id: vacuum.test + from: + - "cleaning" + - "returning" + to: "error" ``` -#### Holding a state +### Holding a state You can use `for` to have the state trigger only fire if the state holds for some time. @@ -278,11 +278,11 @@ state for 30 seconds: ```yaml automation: trigger: - platform: state - entity_id: light.office - # Must stay "on" for 30 seconds - to: "on" - for: "00:00:30" + - platform: state + entity_id: light.office + # Must stay "on" for 30 seconds + to: "on" + for: "00:00:30" ``` Please note, that when holding a state, changes to attributes are ignored and @@ -297,11 +297,11 @@ the time specified, but doesn't care about "playing" or "paused". ```yaml automation: trigger: - platform: state - entity_id: media_player.kitchen - # Not "off" for 30 minutes - from: "off" - for: "00:30:00" + - platform: state + entity_id: media_player.kitchen + # Not "off" for 30 minutes + from: "off" + for: "00:30:00" ``` Please note, that when using `from`, `to` and `for`, only the value of the @@ -313,10 +313,10 @@ same for `for` the time specified, regardless of the current state value. ```yaml automation: trigger: - platform: state - entity_id: media_player.kitchen - # The media player remained in its current state for 1 hour - for: "01:00:00" + - platform: state + entity_id: media_player.kitchen + # The media player remained in its current state for 1 hour + for: "01:00:00" ``` When the `attribute` option is specified, all of the above works, but only @@ -328,11 +328,11 @@ For example, this trigger only fires if the boiler was heating for 10 minutes: ```yaml automation: trigger: - platform: state - entity_id: climate.living_room - attribute: hvac_action - to: "heating" - for: "00:10:00" + - platform: state + entity_id: climate.living_room + attribute: hvac_action + to: "heating" + for: "00:10:00" ``` You can also use templates in the `for` option. @@ -342,16 +342,18 @@ You can also use templates in the `for` option. ```yaml automation: trigger: - platform: state - entity_id: device_tracker.paulus, device_tracker.anne_therese - to: "home" - for: - minutes: "{{ states('input_number.lock_min')|int }}" - seconds: "{{ states('input_number.lock_sec')|int }}" + - platform: state + entity_id: + - device_tracker.paulus + - device_tracker.anne_therese + to: "home" + for: + minutes: "{{ states('input_number.lock_min')|int }}" + seconds: "{{ states('input_number.lock_sec')|int }}" action: - service: lock.lock - target: - entity_id: lock.my_place + - service: lock.lock + target: + entity_id: lock.my_place ``` {% endraw %} @@ -364,9 +366,9 @@ Use quotes around your values for `from` and `to` to avoid the YAML parser from
    -### Sun trigger +## Sun trigger -#### Sunset / Sunrise trigger +### Sunset / Sunrise trigger Fires when the sun is setting or rising, i.e., when the sun elevation reaches 0°. @@ -383,14 +385,14 @@ Since the duration of twilight is different throughout the year, it is recommend ```yaml automation: trigger: - platform: sun - # Possible values: sunset, sunrise - event: sunset - # Optional time offset. This example will trigger 45 minutes before sunset. - offset: "-00:45:00" + - platform: sun + # Possible values: sunset, sunrise + event: sunset + # Optional time offset. This example will trigger 45 minutes before sunset. + offset: "-00:45:00" ``` -#### Sun elevation trigger +### Sun elevation trigger Sometimes you may want more granular control over an automation than simply sunset or sunrise and specify an exact elevation of the sun. This can be used to layer automations to occur as the sun lowers on the horizon or even after it is below the horizon. This is also useful when the "sunset" event is not dark enough outside and you would like the automation to run later at a precise solar angle instead of the time offset such as turning on exterior lighting. For most automations intended to run during dusk or dawn, a number between 0° and -6° is suitable; -4° is used in this example: @@ -398,17 +400,17 @@ Sometimes you may want more granular control over an automation than simply suns ```yaml automation: - alias: "Exterior Lighting on when dark outside" - trigger: - platform: numeric_state - entity_id: sun.sun - attribute: elevation - # Can be a positive or negative number - below: -4.0 - action: - service: switch.turn_on - target: - entity_id: switch.exterior_lighting + - alias: "Exterior Lighting on when dark outside" + trigger: + - platform: numeric_state + entity_id: sun.sun + attribute: elevation + # Can be a positive or negative number + below: -4.0 + action: + - service: switch.turn_on + target: + entity_id: switch.exterior_lighting ``` {% endraw %} @@ -426,7 +428,7 @@ Although the actual amount of light depends on weather, topography and land cove A very thorough explanation of this is available in the Wikipedia article about the [Twilight](https://en.wikipedia.org/wiki/Twilight). -### Tag trigger +## Tag trigger Fires when a [tag](/integrations/tag) is scanned. For example, a NFC tag is scanned using the Home Assistant Companion mobile application. @@ -434,8 +436,8 @@ scanned using the Home Assistant Companion mobile application. ```yaml automation: trigger: - platform: tag - tag_id: A7-6B-90-5F + - platform: tag + tag_id: A7-6B-90-5F ``` Additionally, you can also only trigger if a card is scanned by a specific @@ -444,9 +446,9 @@ device/scanner by setting the `device_id`: ```yaml automation: trigger: - platform: tag - tag_id: A7-6B-90-5F - device_id: 0e19cd3cf2b311ea88f469a7512c307d + - platform: tag + tag_id: A7-6B-90-5F + device_id: 0e19cd3cf2b311ea88f469a7512c307d ``` Or trigger on multiple possible devices for multiple tags: @@ -454,16 +456,16 @@ Or trigger on multiple possible devices for multiple tags: ```yaml automation: trigger: - platform: tag - tag_id: - - A7-6B-90-5F - - A7-6B-15-AC - device_id: - - 0e19cd3cf2b311ea88f469a7512c307d - - d0609cb25f4a13922bb27d8f86e4c821 + - platform: tag + tag_id: + - "A7-6B-90-5F" + - "A7-6B-15-AC" + device_id: + - 0e19cd3cf2b311ea88f469a7512c307d + - d0609cb25f4a13922bb27d8f86e4c821 ``` -### Template trigger +## Template trigger Template triggers work by evaluating a [template](/docs/configuration/templating/) when any of the recognized entities change state. The trigger will fire if the state change caused the template to render 'true' (a non-zero number or any of the strings `true`, `yes`, `on`, `enable`) when it was previously 'false' (anything else). @@ -476,11 +478,11 @@ With template triggers you can also evaluate attribute changes by using is_state ```yaml automation: trigger: - platform: template - value_template: "{% if is_state('device_tracker.paulus', 'home') %}true{% endif %}" + - platform: template + value_template: "{% if is_state('device_tracker.paulus', 'home') %}true{% endif %}" - # If given, will trigger when template remains true for X time. - for: "00:01:00" + # If given, will trigger when template remains true for X time. + for: "00:01:00" ``` {% endraw %} @@ -492,10 +494,10 @@ You can also use templates in the `for` option. ```yaml automation: trigger: - platform: template - value_template: "{{ is_state('device_tracker.paulus', 'home') }}" - for: - minutes: "{{ states('input_number.minutes')|int(0) }}" + - platform: template + value_template: "{{ is_state('device_tracker.paulus', 'home') }}" + for: + minutes: "{{ states('input_number.minutes')|int(0) }}" ``` {% endraw %} @@ -504,23 +506,23 @@ The `for` template(s) will be evaluated when the `value_template` becomes 'true' Templates that do not contain an entity will be rendered once per minute. -### Time trigger +## Time trigger The time trigger is configured to fire once a day at a specific time, or at a specific time on a specific date. There are three allowed formats: -#### Time String +### Time String A string that represents a time to fire on each day. Can be specified as `HH:MM` or `HH:MM:SS`. If the seconds are not specified, `:00` will be used. ```yaml automation: - trigger: - platform: time - # Military time format. This trigger will fire at 3:32 PM - at: "15:32:00" + - trigger: + - platform: time + # Military time format. This trigger will fire at 3:32 PM + at: "15:32:00" ``` -#### Input Datetime +### Input Datetime The Entity ID of an [Input Datetime](/integrations/input_datetime/). @@ -535,9 +537,9 @@ has_date | has_time | Description ```yaml automation: - trigger: - platform: state - entity_id: binary_sensor.motion - to: "on" + - platform: state + entity_id: binary_sensor.motion + to: "on" action: - service: climate.turn_on target: @@ -549,69 +551,68 @@ automation: datetime: > {{ (now().timestamp() + 2*60*60) | timestamp_custom('%Y-%m-%d %H:%M:%S') }} - - trigger: - platform: time - at: input_datetime.turn_off_ac + - platform: time + at: input_datetime.turn_off_ac action: - service: climate.turn_off - target: - entity_id: climate.office + - service: climate.turn_off + target: + entity_id: climate.office ``` {% endraw %} -#### Sensors of datetime device class +### Sensors of datetime device class The Entity ID of a [sensor](/integrations/sensor/) with the "timestamp" device class. ```yaml automation: - trigger: - platform: time - at: sensor.phone_next_alarm + - platform: time + at: sensor.phone_next_alarm action: - service: light.turn_on - target: - entity_id: light.bedroom + - service: light.turn_on + target: + entity_id: light.bedroom ``` -#### Multiple Times +### Multiple Times Multiple times can be provided in a list. Both formats can be intermixed. ```yaml automation: trigger: - platform: time - at: - - input_datetime.leave_for_work - - "18:30:00" + - platform: time + at: + - input_datetime.leave_for_work + - "18:30:00" ``` -### Time pattern trigger +## Time pattern trigger With the time pattern trigger, you can match if the hour, minute or second of the current time matches a specific value. You can prefix the value with a `/` to match whenever the value is divisible by that number. You can specify `*` to match any value (when using the web interface this is required, the fields cannot be left empty). ```yaml automation: trigger: - platform: time_pattern - # Matches every hour at 5 minutes past whole - minutes: 5 + - platform: time_pattern + # Matches every hour at 5 minutes past whole + minutes: 5 automation 2: trigger: - platform: time_pattern - # Trigger once per minute during the hour of 3 - hours: "3" - minutes: "*" + - platform: time_pattern + # Trigger once per minute during the hour of 3 + hours: "3" + minutes: "*" automation 3: trigger: - platform: time_pattern - # You can also match on interval. This will match every 5 minutes - minutes: "/5" + - platform: time_pattern + # You can also match on interval. This will match every 5 minutes + minutes: "/5" ```
    @@ -620,15 +621,15 @@ Do not prefix numbers with a zero - using `'00'` instead of '0' for example will
    -### Webhook trigger +## Webhook trigger Webhook trigger fires when a web request is made to the webhook endpoint: `/api/webhook/`. The webhook endpoint is created automatically when you set it as the `webhook_id` in an automation trigger. ```yaml automation: trigger: - platform: webhook - webhook_id: some_hook_id + - platform: webhook + webhook_id: "some_hook_id" ``` You can run this automation by sending an HTTP POST request to `http://your-home-assistant:8123/api/webhook/some_hook_id`. Here is an example using the **curl** command line program, with an empty data payload: @@ -641,21 +642,21 @@ Webhook endpoints don't require authentication, other than knowing a valid webho Note that a given webhook can only be used in one automation at a time. That is, only one automation trigger can use a specific webhook ID. -### Zone trigger +## Zone trigger Zone trigger fires when an entity is entering or leaving the zone. The entity can be either a person, or a device_tracker. For zone automation to work, you need to have setup a device tracker platform that supports reporting GPS coordinates. This includes [GPS Logger](/integrations/gpslogger/), the [OwnTracks platform](/integrations/owntracks/) and the [iCloud platform](/integrations/icloud/). ```yaml automation: trigger: - platform: zone - entity_id: person.paulus - zone: zone.home - # Event is either enter or leave - event: enter # or "leave" + - platform: zone + entity_id: person.paulus + zone: zone.home + # Event is either enter or leave + event: enter # or "leave" ``` -### Geolocation trigger +## Geolocation trigger Geolocation trigger fires when an entity is appearing in or disappearing from a zone. Entities that are created by a [Geolocation](/integrations/geo_location/) platform support reporting GPS coordinates. Because entities are generated and removed by these platforms automatically, the entity id normally cannot be predicted. Instead, this trigger requires the definition of a `source`, which is directly linked to one of the Geolocation platforms. @@ -666,18 +667,17 @@ This isn't for use with `device_tracker` entities. For those look above at the `
    - ```yaml automation: trigger: - platform: geo_location - source: nsw_rural_fire_service_feed - zone: zone.bushfire_alert_zone - # Event is either enter or leave - event: enter # or "leave" + - platform: geo_location + source: nsw_rural_fire_service_feed + zone: zone.bushfire_alert_zone + # Event is either enter or leave + event: enter # or "leave" ``` -### Device triggers +## Device triggers Device triggers encompass a set of events that are defined by an integration. This includes, for example, state changes of sensors as well as button events from remotes. [MQTT device triggers](/integrations/device_trigger.mqtt/) are set up through autodiscovery. @@ -686,7 +686,7 @@ In contrast to state triggers, device triggers are tied to a device and not nece To use a device trigger, set up an automation through the browser frontend. If you would like to use a device trigger for an automation that is not managed through the browser frontend, you can copy the YAML from the trigger widget in the frontend and paste it into your automation's trigger list. -### Multiple triggers +## Multiple triggers It is possible to specify multiple triggers for the same rule. To do so just prefix the first line of each trigger with a dash (-) and indent the next lines accordingly. Whenever one of the triggers fires, [processing](#what-are-triggers) of your automation rule begins. @@ -701,7 +701,7 @@ automation: event: sunset ``` -### Multiple Entity IDs for the same Trigger +## Multiple Entity IDs for the same Trigger It is possible to specify multiple entities for the same trigger. To do so add multiple entities using a nested list. The trigger will fire and start, [processing](#what-are-triggers) your automation each time the trigger is true for each entity listed. diff --git a/source/_docs/automation/yaml.markdown b/source/_docs/automation/yaml.markdown index 77a869289f0..b8bc80f455a 100644 --- a/source/_docs/automation/yaml.markdown +++ b/source/_docs/automation/yaml.markdown @@ -15,8 +15,8 @@ automation: !include automations.yaml # Labeled automation block automation kitchen: -- trigger: - platform: ... + - trigger: + - platform: ... ``` You can add as many labeled `automation` blocks as you want. @@ -53,54 +53,53 @@ automation my_lights: before: "23:00:00" action: # With a single service call, we don't need a '-' before service - though you can if you want to - service: homeassistant.turn_on - target: - entity_id: group.living_room + - service: homeassistant.turn_on + target: + entity_id: group.living_room # Turn off lights when everybody leaves the house - alias: "Rule 2 - Away Mode" trigger: - platform: state - entity_id: all - to: "not_home" - action: - service: light.turn_off - target: + - platform: state entity_id: all + to: "not_home" + action: + - service: light.turn_off + target: + entity_id: all # Notify when Paulus leaves the house in the evening - alias: "Leave Home notification" trigger: - platform: zone - event: leave - zone: zone.home - entity_id: device_tracker.paulus + - platform: zone + event: leave + zone: zone.home + entity_id: device_tracker.paulus condition: - condition: time - after: "20:00" + - condition: time + after: "20:00" action: - service: notify.notify - data: - message: "Paulus left the house" + - service: notify.notify + data: + message: "Paulus left the house" # Send a notification via Pushover with the event of a Xiaomi cube. Custom event from the Xiaomi component. - alias: "Xiaomi Cube Action" initial_state: false trigger: - platform: event - event_type: cube_action - event_data: - entity_id: binary_sensor.cube_158d000103a3de + - platform: event + event_type: cube_action + event_data: + entity_id: binary_sensor.cube_158d000103a3de action: - service: notify.pushover - data: - title: "Cube event detected" - message: "Cube has triggered this event: {{ trigger.event }}" + - service: notify.pushover + data: + title: "Cube event detected" + message: "Cube has triggered this event: {{ trigger.event }}" ``` {% endraw %} - ## Extra options When writing automations directly in YAML, you will have access to advanced options that are not available in the user interface. @@ -114,7 +113,7 @@ automation: - alias: "Automation Name" initial_state: false trigger: - - platform: ... + - platform: ... ``` ## Migrating your YAML automations to `automations.yaml` diff --git a/source/_docs/blueprint/schema.markdown b/source/_docs/blueprint/schema.markdown index c514467a495..2f88a109dc4 100644 --- a/source/_docs/blueprint/schema.markdown +++ b/source/_docs/blueprint/schema.markdown @@ -171,10 +171,10 @@ mode: restart max_exceeded: silent trigger: - platform: state - entity_id: !input motion_entity - from: "off" - to: "on" + - platform: state + entity_id: !input motion_entity + from: "off" + to: "on" action: - service: light.turn_on diff --git a/source/_docs/blueprint/tutorial.markdown b/source/_docs/blueprint/tutorial.markdown index d26eaa99bed..97bef2a2254 100644 --- a/source/_docs/blueprint/tutorial.markdown +++ b/source/_docs/blueprint/tutorial.markdown @@ -191,17 +191,17 @@ blueprint: domain: light trigger: - platform: state - entity_id: !input motion_sensor + - platform: state + entity_id: !input motion_sensor action: - service: > - {% if trigger.to_state.state == "on" %} - light.turn_on - {% else %} - light.turn_off - {% endif %} - target: !input target_light + - service: > + {% if trigger.to_state.state == "on" %} + light.turn_on + {% else %} + light.turn_off + {% endif %} + target: !input target_light ``` {% endraw %} diff --git a/source/_docs/configuration/basic.markdown b/source/_docs/configuration/basic.markdown index d1d5396947d..8a42d18bcd5 100644 --- a/source/_docs/configuration/basic.markdown +++ b/source/_docs/configuration/basic.markdown @@ -14,17 +14,17 @@ homeassistant: longitude: 117.22743 elevation: 430 unit_system: metric - time_zone: America/Los_Angeles + time_zone: "America/Los_Angeles" external_url: "https://www.example.com" internal_url: "http://homeassistant.local:8123" allowlist_external_dirs: - - /usr/var/dumping-ground - - /tmp + - "/usr/var/dumping-ground" + - "/tmp" allowlist_external_urls: - "http://images.com/image1.png" media_dirs: - media: /media - recordings: /mnt/recordings + media: "/media" + recordings: "/mnt/recordings" legacy_templates: false ``` diff --git a/source/_docs/configuration/devices.markdown b/source/_docs/configuration/devices.markdown index 0f93b43382a..61e10fce226 100644 --- a/source/_docs/configuration/devices.markdown +++ b/source/_docs/configuration/devices.markdown @@ -25,7 +25,7 @@ sensor: state_topic: "home/kitchen/temperature" name: "MQTT Sensor 2" - platform: rest - resource: http://IP_ADDRESS/ENDPOINT + resource: "http://IP_ADDRESS/ENDPOINT" name: "Weather" switch: @@ -49,7 +49,7 @@ sensor kitchen: sensor weather: platform: rest - resource: http://IP_ADDRESS/ENDPOINT + resource: "http://IP_ADDRESS/ENDPOINT" name: "Weather" switch 1: @@ -65,10 +65,12 @@ Once you have several devices set up, it is time to organize them into groups. Each group consists of a name and a list of entity IDs. Entity IDs can be retrieved from the web interface by using the {% my developer_states title="States page in the Developer Tools" %}. ```yaml -# Example configuration.yaml entry showing two styles +# Example configuration.yaml entry group: living_room: - entities: light.table_lamp, switch.ac + entities: + - light.table_lamp + - switch.ac bedroom: entities: - light.bedroom diff --git a/source/_docs/configuration/packages.markdown b/source/_docs/configuration/packages.markdown index 21b49a04cfd..9680a6b30e1 100644 --- a/source/_docs/configuration/packages.markdown +++ b/source/_docs/configuration/packages.markdown @@ -57,21 +57,22 @@ light: There are some rules for packages that will be merged: 1. Platform based integrations (`light`, `switch`, etc) can always be merged. -2. Components where entities are identified by a key that will represent the entity_id (`{key: config}`) need to have unique 'keys' between packages and the main configuration file. +2. Components where entities are identified by a key that will represent the entity_id (`{key: config}`) need to have unique 'keys' between packages and the main configuration file. For example if we have the following in the main configuration. You are not allowed to re-use "my_input" again for `input_boolean` in a package: - + ```yaml input_boolean: my_input: ``` + 3. Any integration that is not a platform [1], or dictionaries with Entity ID keys [2] can only be merged if its keys, except those for lists, are solely defined once.
    Components inside packages can only specify platform entries using configuration style 1, where all the platforms are grouped under the integration name.
    -### Create a packages folder +## Create a packages folder One way to organize packages is to create a folder named "packages" in your Home Assistant configuration directory. In the packages directory you can store any number of packages in a YAML file. This entry in your `configuration.yaml` will load all packages: @@ -101,7 +102,7 @@ subsystem1_functionality1: automation: ``` -### Customizing entities with packages +## Customizing entities with packages It is possible to [customize entities](/docs/configuration/customizing-devices/) within packages. Just create your customization entries under: diff --git a/source/_docs/configuration/platform_options.markdown b/source/_docs/configuration/platform_options.markdown index af528461dc9..f632baa4128 100644 --- a/source/_docs/configuration/platform_options.markdown +++ b/source/_docs/configuration/platform_options.markdown @@ -9,7 +9,7 @@ These options are being phased out and are only available for single platform in Some integrations or platforms (those that are based on the [entity](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/helpers/entity.py) class) allows various extra options to be set. -### Entity namespace +## Entity namespace By setting an entity namespace, all entities will be prefixed with that namespace. That way `light.bathroom` can become `light.holiday_house_bathroom`. @@ -20,7 +20,7 @@ light: entity_namespace: holiday_house ``` -### Scan Interval +## Scan Interval Platforms that require polling will be polled in an interval specified by the main component. For example a light will check every 30 seconds for a changed state. It is possible to overwrite this scan interval for any platform that is being polled by specifying a `scan_interval` configuration key. In the example below we set up the `your_lights` platform but tell Home Assistant to poll the devices every 10 seconds instead of the default 30 seconds. diff --git a/source/_docs/configuration/remote.markdown b/source/_docs/configuration/remote.markdown index a829d9e2b7e..975afd8884a 100644 --- a/source/_docs/configuration/remote.markdown +++ b/source/_docs/configuration/remote.markdown @@ -15,10 +15,6 @@ Remember to follow the [securing checklist](/docs/configuration/securing/) befor
    -
    -Home Assistant no longer support remote access via IP address since release 0.77, you have to use a domain name. -
    - The most common approach is to set up port forwarding (for any port) from your router to port 8123 on the computer that is hosting Home Assistant. General instructions on how to do this can be found by searching ` port forwarding instructions`. You can use any free port on your router and forward that to port 8123. A problem with making a port accessible is that some Internet Service Providers only offer dynamic IPs. This can cause you to lose access to Home Assistant while away. You can solve this by using a free Dynamic DNS service like [DuckDNS](https://www.duckdns.org/). diff --git a/source/_docs/configuration/secrets.markdown b/source/_docs/configuration/secrets.markdown index 8dec4f4c6c5..9fac0e3d9ce 100644 --- a/source/_docs/configuration/secrets.markdown +++ b/source/_docs/configuration/secrets.markdown @@ -30,7 +30,7 @@ homeassistant: The `secrets.yaml` file contains the corresponding password assigned to the identifier. ```yaml -http_password: YOUR_PASSWORD +http_password: "YOUR_PASSWORD" ``` ## Debugging secrets diff --git a/source/_docs/configuration/splitting_configuration.markdown b/source/_docs/configuration/splitting_configuration.markdown index 5bfbc9d3233..bb7edc22e6a 100644 --- a/source/_docs/configuration/splitting_configuration.markdown +++ b/source/_docs/configuration/splitting_configuration.markdown @@ -16,14 +16,14 @@ In this lighter version we will still need what could be called the core snippet ```yaml homeassistant: # Name of the location where Home Assistant is running - name: My Home Assistant Instance + name: "My Home Assistant Instance" # Location required to calculate the time the sun rises and sets latitude: 37 longitude: -121 # 'metric' for Metric, 'imperial' for Imperial unit_system: imperial # Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones - time_zone: America/Los_Angeles + time_zone: "America/Los_Angeles" customize: !include customize.yaml ``` @@ -38,18 +38,18 @@ history: frontend: logbook: http: - api_password: ImNotTelling! + api_password: "ImNotTelling!" ifttt: - key: [nope] + key: ["nope"] wink: - access_token: [wouldn't you] - refresh_token: [like to know] + access_token: ["wouldn't you"] + refresh_token: ["like to know"] zwave: - usb_path: /dev/ttyUSB0 - config_path: /usr/local/share/python-openzwave/config + usb_path: "/dev/ttyUSB0" + config_path: "/usr/local/share/python-openzwave/config" polling_interval: 10000 mqtt: @@ -88,7 +88,7 @@ Nesting `!include`s (having an `!include` within a file that is itself `!include ```yaml light: - platform: group - name: Bedside Lights + name: "Bedside Lights" entities: - light.left_bedside_light - light.right_bedside_light @@ -104,7 +104,7 @@ where `light-groups.yaml` might look like: ```yaml - platform: group - name: Outside Lights + name: "Outside Lights" entities: - light.porch_lights - light.patio_lights @@ -114,11 +114,11 @@ with `light-switches.yaml` containing: ```yaml - platform: switch - name: Patio Lights + name: "Patio Lights" entity_id: switch.patio_lights - platform: switch - name: Floor Lamp + name: "Floor Lamp" entity_id: switch.floor_lamp_plug ``` @@ -129,8 +129,8 @@ Let's look at the `device_tracker.yaml` file from our example: ```yaml - platform: owntracks - platform: nmap_tracker - hosts: 192.168.2.0/24 home_interval: 3 + hosts: 192.168.2.0/24 track_new_devices: true interval_seconds: 40 @@ -164,15 +164,15 @@ This (large) sensor configuration gives us another example: #### STEAM FRIENDS ################################## - platform: steam_online - api_key: [not telling] + api_key: ["not telling"] accounts: - 76561198012067051 #### TIME/DATE ################################## - platform: time_date display_options: - - 'time' - - 'date' + - "time" + - "date" - platform: worldclock time_zone: Etc/UTC name: "UTC" @@ -303,7 +303,7 @@ alexa: action: service: notify.pushover data: - message: Your location has been queried via Alexa. + message: "Your location has been queried via Alexa." speech: type: plaintext text: > @@ -341,7 +341,7 @@ alexa: action: service: notify.pushover data: - message: Your location has been queried via Alexa. + message: "Your location has been queried via Alexa." speech: type: plaintext text: > @@ -376,22 +376,22 @@ speech: automation: - alias: "Automation 1" trigger: - platform: state - entity_id: device_tracker.iphone - to: "home" + - platform: state + entity_id: device_tracker.iphone + to: "home" action: - service: light.turn_on - target: - entity_id: light.entryway + - service: light.turn_on + target: + entity_id: light.entryway - alias: "Automation 2" trigger: - platform: state - entity_id: device_tracker.iphone - from: "home" + - platform: state + entity_id: device_tracker.iphone + from: "home" action: - service: light.turn_off - target: - entity_id: light.entryway + - service: light.turn_off + target: + entity_id: light.entryway ``` can be turned into: @@ -407,22 +407,22 @@ automation: !include_dir_merge_list automation/ ```yaml - alias: "Automation 1" trigger: - platform: state - entity_id: device_tracker.iphone - to: "home" + - platform: state + entity_id: device_tracker.iphone + to: "home" action: - service: light.turn_on - target: - entity_id: light.entryway + - service: light.turn_on + target: + entity_id: light.entryway - alias: "Automation 2" trigger: - platform: state - entity_id: device_tracker.iphone - from: "home" + - platform: state + entity_id: device_tracker.iphone + from: "home" action: - service: light.turn_off - target: - entity_id: light.entryway + - service: light.turn_off + target: + entity_id: light.entryway ``` It is important to note that when using `!include_dir_merge_list`, you must include a list in each file (each list item is denoted with a hyphen [-]). Each file may contain one or more entries. @@ -434,17 +434,17 @@ It is important to note that when using `!include_dir_merge_list`, you must incl ```yaml group: bedroom: - name: Bedroom + name: "Bedroom" entities: - light.bedroom_lamp - light.bedroom_overhead hallway: - name: Hallway + name: "Hallway" entities: - light.hallway - thermostat.home front_yard: - name: Front Yard + name: "Front Yard" entities: - light.front_porch - light.security @@ -465,7 +465,7 @@ group: !include_dir_merge_named group/ ```yaml bedroom: - name: Bedroom + name: "Bedroom" entities: - light.bedroom_lamp - light.bedroom_overhead @@ -480,7 +480,7 @@ hallway: ```yaml front_yard: - name: Front Yard + name: "Front Yard" entities: - light.front_porch - light.security diff --git a/source/_docs/configuration/templating.markdown b/source/_docs/configuration/templating.markdown index 3f3852ffa3c..73b694f2075 100644 --- a/source/_docs/configuration/templating.markdown +++ b/source/_docs/configuration/templating.markdown @@ -29,6 +29,7 @@ The frontend has a {% my developer_templates title="template editor tool" %} to Templates can get big pretty fast. To keep a clear overview, consider using YAML multiline strings to define your templates: {% raw %} + ```yaml script: msg_who_is_home: @@ -42,6 +43,7 @@ script: Paulus is at {{ states('device_tracker.paulus') }}. {% endif %} ``` + {% endraw %} ### Important Template Rules @@ -87,20 +89,24 @@ Besides the normal [state object methods and properties](/topics/state_object/), The next two statements result in the same value if the state exists. The second one will result in an error if the state does not exist. {% raw %} + ```text {{ states('device_tracker.paulus') }} {{ states.device_tracker.paulus.state }} ``` + {% endraw %} Print out a list of all the sensor states: {% raw %} + ```text {% for state in states.sensor %} {{ state.entity_id }}={{ state.state }}, {% endfor %} ``` + {% endraw %} Other state examples: @@ -128,8 +134,8 @@ Other state examples: {{ as_timestamp(now()) - as_timestamp(states.binary_sensor.garage_door.last_changed) }} {{ as_local(states.sensor.time.last_changed) }} - ``` + {% endraw %} ### Attributes @@ -141,6 +147,7 @@ You can print an attribute with `state_attr` if state is defined. #### Attributes examples {% raw %} + ```text {% if states.device_tracker.paulus %} {{ state_attr('device_tracker.paulus', 'battery') }} @@ -148,11 +155,13 @@ You can print an attribute with `state_attr` if state is defined. ?? {% endif %} ``` + {% endraw %} With strings: {% raw %} + ```text {% set tracker_name = "paulus"%} @@ -162,6 +171,7 @@ With strings: ?? {% endif %} ``` + {% endraw %} ### Working with Groups @@ -173,22 +183,26 @@ The `expand` function and filter can be used to sort entities and expand groups. #### Expand examples {% raw %} + ```text {% for tracker in expand('device_tracker.paulus', 'group.child_trackers') %} {{ state_attr(tracker, 'battery') }} {%- if not loop.last %}, {% endif -%} {% endfor %} ``` + {% endraw %} The same thing can also be expressed as a filter: {% raw %} + ```text {{ expand(['device_tracker.paulus', 'group.child_trackers']) | selectattr("attributes.battery", 'defined') | join(', ', attribute="attributes.battery") }} ``` + {% endraw %} ### Time @@ -208,10 +222,12 @@ The same thing can also be expressed as a filter: - `timedelta` returns a timedelta object and accepts the same arguments as the Python `datetime.timedelta` function -- days, seconds, microseconds, milliseconds, minutes, hours, weeks. {% raw %} + ```yaml # 77 minutes before curret time. {{ now() - timedelta( hours = 1, minutes = 17 ) }} ``` + {% endraw %} - Filter `timestamp_local` converts an UNIX timestamp to its string representation as date/time in your local timezone. @@ -219,13 +235,13 @@ The same thing can also be expressed as a filter: - Filter `timestamp_custom(format_string, local_time=True)` converts an UNIX timestamp to its string representation based on a custom format, the use of a local timezone is default. Supports the standard [Python time formatting options](https://docs.python.org/3/library/time.html#time.strftime).
    - + [UNIX timestamp](https://en.wikipedia.org/wiki/Unix_time) is the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970. Therefore, if used as a function's argument, it can be substituted with a numeric value (`int` or `float`).
    - + If your template is returning a timestamp that should be displayed in the frontend (e.g., as a sensor entity with `device_class: timestamp`), you have to ensure that it is the ISO 8601 format (meaning it has the "T" separator between the date and time portion). Otherwise, frontend rendering on macOS and iOS devices will show an error. The following value template would result in such an error: {% raw %} @@ -245,9 +261,11 @@ To fix it, enforce the ISO conversion via `isoformat()`:
    {% raw %} + ```yaml {{ 120 | timestamp_local }} ``` + {% endraw %} ### To/From JSON @@ -263,20 +281,24 @@ In this example, the special character '°' will be automatically escaped in ord *Template* {% raw %} + ```text {% set temp = {'temperature': 25, 'unit': '°C'} %} stringified object: {{ temp }} object|to_json: {{ temp|to_json }} ``` + {% endraw %} *Output* {% raw %} + ```text stringified object: {'temperature': 25, 'unit': '°C'} object|to_json: {"temperature": 25, "unit": "\u00b0C"} ``` + {% endraw %} Conversely, `from_json` can be used to de-serialize a JSON string back into an object to make it possible to easily extract usable data. @@ -284,18 +306,22 @@ Conversely, `from_json` can be used to de-serialize a JSON string back into an o *Template* {% raw %} + ```text {% set temp = '{"temperature": 25, "unit": "\u00b0C"}'|from_json %} The temperature is {{ temp.temperature }}{{ temp.unit }} ``` + {% endraw %} *Output* {% raw %} + ```text The temperature is 25°C ``` + {% endraw %} ### Distance @@ -311,6 +337,7 @@ If only one location is passed in, Home Assistant will measure the distance from {% raw %} ```text + Using Lat Lng coordinates: {{ distance(123.45, 123.45) }} Using State: {{ distance(states.device_tracker.paulus) }} @@ -319,6 +346,7 @@ These can also be combined in any combination: {{ distance(123.45, 123.45, 'device_tracker.paulus') }} {{ distance('device_tracker.anne_therese', 'device_tracker.paulus') }} ``` + {% endraw %} #### Closest examples @@ -326,35 +354,42 @@ These can also be combined in any combination: The closest function and filter will find the closest entity to the Home Assisant location: {% raw %} + ```text Query all entities: {{ closest(states) }} Query all entities of a specific domain: {{ closest(states.device_tracker) }} Query all entities in group.children: {{ closest('group.children') }} Query all entities in group.children: {{ closest(states.group.children) }} ``` + {% endraw %} Find entities closest to a coordinate or another entity. All previous arguments still apply for second argument. {% raw %} + ```text Closest to a coordinate: {{ closest(23.456, 23.456, 'group.children') }} Closest to an entity: {{ closest('zone.school', 'group.children') }} Closest to an entity: {{ closest(states.zone.school, 'group.children') }} ``` + {% endraw %} Since closest returns a state, we can combine it with distance too. {% raw %} + ```text {{ closest(states).name }} is {{ distance(closest(states)) }} kilometers away. ``` + {% endraw %} The last argument of the closest function has an implicit `expand`, and can take any iterable sequence of states or entity IDs, and will expand groups: {% raw %} + ```text Closest out of given entities: {{ closest(['group.children', states.device_tracker]) }} @@ -364,8 +399,12 @@ Closest to some entity: {{ closest(states.zone.school, ['group.children', states.device_tracker]) }} ``` +{% endraw %} + It will also work as a filter over an iterable group of entities or groups: +{% raw %} + ```text Closest out of given entities: {{ ['group.children', states.device_tracker] | closest }} @@ -441,9 +480,11 @@ This means that if the incoming values looks like the sample below: The template for `on` would be: {% raw %} + ```yaml '{{value_json.on}}' ``` + {% endraw %} Nested JSON in a response is supported as well: @@ -464,42 +505,49 @@ Nested JSON in a response is supported as well: Just use the "Square bracket notation" to get the value. {% raw %} + ```yaml "{{ value_json['values']['temp'] }}" ``` + {% endraw %} The following overview contains a couple of options to get the needed values: +{% raw %} + ```text # Incoming value: {"primes": [2, 3, 5, 7, 11, 13]} # Extract third prime number -{% raw %}{{ value_json.primes[2] }}{% endraw %} +{{ value_json.primes[2] }} # Format output -{% raw %}{{ "%+.1f" | value_json }}{% endraw %} +{{ "%+.1f" | value_json }} # Math -{% raw %}{{ value_json | float * 1024 }}{% endraw %} -{% raw %}{{ float(value_json) * (2**10) }}{% endraw %} -{% raw %}{{ value_json | log }}{% endraw %} -{% raw %}{{ log(1000, 10) }}{% endraw %} -{% raw %}{{ sin(pi / 2) }}{% endraw %} -{% raw %}{{ cos(tau) }}{% endraw %} -{% raw %}{{ tan(pi) }}{% endraw %} -{% raw %}{{ sqrt(e) }}{% endraw %} +{{ value_json | float * 1024 }} +{{ float(value_json) * (2**10) }} +{{ value_json | log }} +{{ log(1000, 10) }} +{{ sin(pi / 2) }} +{{ cos(tau) }} +{{ tan(pi) }} +{{ sqrt(e) }} # Timestamps -{% raw %}{{ value_json.tst | timestamp_local }}{% endraw %} -{% raw %}{{ value_json.tst | timestamp_utc }}{% endraw %} -{% raw %}{{ value_json.tst | timestamp_custom('%Y' True) }}{% endraw %} +{{ value_json.tst | timestamp_local }} +{{ value_json.tst | timestamp_utc }} +{{ value_json.tst | timestamp_custom('%Y' True) }} ``` -To evaluate a response, go to **Developer Tools** -> **Template**, create your output in "Template editor", and check the result. +{% endraw %} + +To evaluate a response, go to **{% my developer_templates title="Developer Tools -> Template" %}**, create your output in "Template editor", and check the result. {% raw %} + ```yaml {% set value_json= {"name":"Outside", @@ -511,6 +559,7 @@ To evaluate a response, go to **Developer Tools** -> **Template**, create your o {{value_json.data.hum[:-1]}} ``` + {% endraw %} ## Some more things to keep in mind @@ -524,9 +573,11 @@ If your template uses an `entity_id` that begins with a number (example: `states The default priority of operators is that the filter (`|`) has priority over everything except brackets. This means that: {% raw %} + ```yaml {{ states('sensor.temperature') | float / 10 | round(2) }} ``` + {% endraw %} Would round `10` to 2 decimal places, then divide `states('sensor.temperature')` by `10` (rounded to 2 decimal places so 10.00). This behavior is maybe not the one expected, but priority rules imply that. diff --git a/source/_docs/configuration/troubleshooting.markdown b/source/_docs/configuration/troubleshooting.markdown index 34d3677582a..399853c9148 100644 --- a/source/_docs/configuration/troubleshooting.markdown +++ b/source/_docs/configuration/troubleshooting.markdown @@ -13,7 +13,7 @@ Whenever an integration or configuration option results in a warning, it will be When an integration does not show up, many different things can be the case. Before you try any of these steps, make sure to look at the `home-assistant.log` file and see if there are any errors related to your integration you are trying to set up. -If you have incorrect entries in your configuration files you can use the configuration check command (below) to assist in identifying them. +If you have incorrect entries in your configuration files you can use the configuration check command (below) to assist in identifying them. ### Problems with the configuration diff --git a/source/_docs/configuration/yaml.markdown b/source/_docs/configuration/yaml.markdown index 1bf3d3d238c..e0e4ff9d4de 100644 --- a/source/_docs/configuration/yaml.markdown +++ b/source/_docs/configuration/yaml.markdown @@ -5,7 +5,7 @@ description: "Details about YAML to configure Home Assistant." Home Assistant uses the [YAML](https://yaml.org/) syntax for configuration. YAML might take a while to get used to but is really powerful in allowing you to express complex configurations. -While more and more integrations are configured through the UI, for some, you will add code in your `configuration.yaml` file to specify its settings. +While more and more integrations are configured through the UI, for some, you will add code in your `configuration.yaml` file to specify its settings. The following example entry assumes that you would like to set up the [notify integration](/integrations/notify) with the [pushbullet platform](/integrations/pushbullet). @@ -41,8 +41,8 @@ The other properties (like `name:`) are specified using mappings. Note that the ```yaml input_select: threat: - name: Threat level -# A collection is used for options + name: "Threat level" + # A collection is used for options options: - 0 - 1 @@ -56,9 +56,9 @@ The following example shows nesting a collection of mappings in a mapping. In Ho ```yaml sensor: - platform: mqtt - state_topic: sensor/topic + state_topic: "sensor/topic" - platform: mqtt - state_topic: sensor2/topic + state_topic: "sensor2/topic" ``` ## Including values @@ -111,7 +111,7 @@ Home Assistant is case sensitive, a state of `'on'` is not the same as `'On'` or If you're having trouble, check the case that Home Assistant is reporting in the dev-state menu, under *Developer tools*. -### Booleans +### Booleans YAML treats `Y`, `true`, `Yes`, `ON` all as `true` and `n`, `FALSE`, `No`, `off` as `false`. This means that if you want to set the state of an entity to `on` you *must* quote it as `'on'` otherwise it will be translated as setting the state to true. The same applies to `off`. From 9a3fa3dcd73913f6c202bfaa9db2fff0d9bda66c Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 2 Mar 2021 16:12:07 -0500 Subject: [PATCH 15/90] Update example zwave_js_event value notification event to include new keys (#16815) --- source/_integrations/zwave_js.markdown | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source/_integrations/zwave_js.markdown b/source/_integrations/zwave_js.markdown index edd74a0d612..84fa202c215 100644 --- a/source/_integrations/zwave_js.markdown +++ b/source/_integrations/zwave_js.markdown @@ -168,12 +168,15 @@ Value Notification example: "home_id": "974823419", "endpoint": 0, "device_id": "ad8098fe80980974", - "command_class": 32, - "command_class_name": "Basic", + "command_class": 91, + "command_class_name": "Central Scene", "label": "Event value", - "property_name": "event", - "property_key_name": "some value", - "value": 255, + "property": "scene", + "property_name": "scene", + "property_key": "001", + "property_key_name": "001", + "value": "KeyPressed", + "value_raw": 0 } ``` From 53293b63d0cf5583eba70dbc15dfc5f2a1e54698 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Wed, 3 Mar 2021 09:37:15 +0100 Subject: [PATCH 16/90] Add list of commands (#16807) Co-authored-by: Franck Nijhof --- source/_integrations/philips_js.markdown | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/source/_integrations/philips_js.markdown b/source/_integrations/philips_js.markdown index aa3316e9a17..2fdccf4cedc 100644 --- a/source/_integrations/philips_js.markdown +++ b/source/_integrations/philips_js.markdown @@ -3,6 +3,7 @@ title: Philips TV description: Instructions on how to add Philips TVs to Home Assistant. ha_category: - Media Player + - Remote ha_iot_class: Local Polling ha_release: 0.34 ha_codeowners: @@ -39,3 +40,74 @@ Instructions on how to activate the API and if your model is supported can be fo ### Turn on device The Philips TV does not always support turning on via the API. You can either turn it on via IR blaster or on som models WOL. To trigger this command from the entities, the integration exposes a `device trigger` that can be setup to execute when the `media_player` is asked to turn on. + +### Remote + +The integration provides a remote entity for sending remote key presses directly to the TV. The following list of commands are available for use with the `remote.send_command` service. + +| Command | Comment | +| ---------------- | ----------------------------------------- | +| Standby | | +| CursorUp | | +| CursorDown | | +| CursorLeft | | +| CursorRight | | +| Confirm | | +| Back | | +| Exit | | +| WatchTV | | +| Home | | +| Source | | +| List | | +| Find | | +| Options | | +| Adjust | | +| RedColour | | +| GreenColour | | +| YellowColour | | +| BlueColour | | +| Play | | +| PlayPause | Mapped to same as Play on Android devices | +| Pause | | +| FastForward | | +| Stop | | +| Rewind | | +| Record | | +| ChannelStepUp | | +| ChannelStepDown | | +| Digit0 | | +| Digit1 | | +| Digit2 | | +| Digit3 | | +| Digit4 | | +| Digit5 | | +| Digit6 | | +| Digit7 | | +| Digit8 | | +| Digit9 | | +| Dot | | +| VolumeUp | | +| VolumeDown | | +| Mute | | +| Teletext | | +| Subtitle | | +| ClosedCaption | | +| TvGuide | | +| Info | | +| AmbilightOnOff | | +| Viewmode | | +| 3dFormat | | +| Multiview | | +| PictureStyle | | +| 3dDepth | | +| SoundStyle | | +| SurroundMode | | +| HeadphonesVolume | | +| 2PlayerGaming | | +| Setup | | +| WhiteColour | | +| PowerOn | | +| PowerOff | Mapped to same as Standby on Android | +| Online | | +| SmartTV | | +| PhilipsMenu | | From 3aee41e2c3221e0f24205ed63a0263c0252cfb90 Mon Sep 17 00:00:00 2001 From: Nick Adams <4012017+Nick-Adams-AU@users.noreply.github.com> Date: Wed, 3 Mar 2021 19:10:03 +1000 Subject: [PATCH 17/90] Add airflow min-max service description (#16823) Co-authored-by: Franck Nijhof --- source/_integrations/izone.markdown | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/_integrations/izone.markdown b/source/_integrations/izone.markdown index 887535b5904..819c9ddb346 100644 --- a/source/_integrations/izone.markdown +++ b/source/_integrations/izone.markdown @@ -122,3 +122,23 @@ logger: ``` This will help you to find network connection issues etc. + +## Services + +### Service `izone.airflow_min` + +Set the minimum airflow for a particular zone. + +| Service data attribute | Optional | Description | +| ---------------------- | -------- | ----------- | +| `entity_id` | yes | izone Zone entity. For example `climate.bed_2` +| `airflow` | no | Airflow percent in 5% increments + +### Service `izone.airflow_max` + +Set the maximum airflow for a particular zone. + +| Service data attribute | Optional | Description | +| ---------------------- | -------- | ----------- | +| `entity_id` | yes | izone Zone entity. For example `climate.bed_2` +| `airflow` | no | Airflow percent in 5% increments From 66f7d0c63067b992f0d5984c613e1a25d3a74a8d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 6 Mar 2021 21:42:16 -1000 Subject: [PATCH 18/90] Change default homekit ports to 21063 and 21064 (#16882) --- source/_integrations/homekit.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/_integrations/homekit.markdown b/source/_integrations/homekit.markdown index 21dbb182706..f7ce387e180 100644 --- a/source/_integrations/homekit.markdown +++ b/source/_integrations/homekit.markdown @@ -57,7 +57,7 @@ homekit: camera.back_porch: support_audio: True - name: HASS Bridge 2 - port: 56332 + port: 21065 filter: include_domains: - light @@ -78,7 +78,7 @@ homekit: description: Port for the HomeKit extension. If you are adding more than one instance they need to have different values for port. required: false type: integer - default: 51827 + default: 21063 name: description: Need to be individual for each instance of Home Assistant using the integration on the same local network. Between `3` and `25` characters. Alphanumeric and spaces allowed. required: false From 2d66a00aa08c399d8983231f0ec6385f9fd93498 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 15 Mar 2021 13:58:22 +0100 Subject: [PATCH 19/90] Deprecate HomeKit auto start (#16874) --- source/_integrations/homekit.markdown | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/source/_integrations/homekit.markdown b/source/_integrations/homekit.markdown index 4424b3dabef..cba7290dd81 100644 --- a/source/_integrations/homekit.markdown +++ b/source/_integrations/homekit.markdown @@ -83,11 +83,6 @@ homekit: required: true type: map keys: - auto_start: - description: Flag if the HomeKit Server should start automatically after the Home Assistant Core Setup is done. ([Disable Auto Start](#disable-auto-start)) - required: false - type: boolean - default: true port: description: Port for the HomeKit extension. If you are adding more than one instance they need to have different values for port. required: false @@ -304,12 +299,6 @@ Currently, this integration uses the `entity_id` to generate a unique `accessory The HomeKit Accessory Protocol Specification only allows a maximum of 150 unique accessories (`aid`) per bridge. Be mindful of this when configuring the filter(s). If you plan on exceeding the 150 devices limit, it is possible to create multiple bridges. If you need specific configuration for some entities via `entity_config` be sure to add them to a bridge configured via `YAML`. -### Persistence Storage - -Unfortunately, `HomeKit` doesn't support any persistent storage - only the configuration for accessories that are added to the `Home Assistant Bridge` are kept. To avoid problems, it is recommended to use an automation to always start `HomeKit` with at least the same entities setup. If, for some reason, some entities are not set up, their configuration will be deleted. (State unknown or similar will not cause any issues.) - -A common situation might be if you decide to disable parts of the configuration for testing. Please make sure to disable `auto start` and `turn off` the `Start HomeKit` automation (if you have one). - ### Multiple HomeKit instances If you create a HomeKit integration via the UI (i.e., **Configuration** >> **Integrations**), it must be configured via the UI **only**. While the UI only offers limited configuration options at the moment, any attempt to configure a HomeKit instance created in the UI via the `configuration.yaml` file will result in another instance of HomeKit running on a different port. @@ -338,10 +327,6 @@ To add a single entity in accessory mode: 5. Complete the options flow 6. [Pair the accessory](#setup). -## Disable Auto Start - -It is not needed (anymore) to disable `Auto Start` for all accessories to be available for `HomeKit` as Home Assistant restores all entities on start instantly. - ## Configure Filter By default, no entity will be excluded. To limit which entities are being exposed to `HomeKit`, you can use the `filter` parameter. Keep in mind only [supported components](#supported-components) can be added. @@ -537,10 +522,6 @@ Pairing works fine when the filter is set to only include `demo.demo`, but fails ### Issues during normal use -#### Some of my devices don't show up - Z-Wave / Discovery - -See [disable auto start](#disable-auto-start) - #### My entity doesn't show up Check if the domain of your entity is [supported](#supported-components). If it is, check your [filter](#configure-filter) settings. Make sure the spelling is correct, especially if you use `include_entities`. From fa0c50fa807c4cac98fb0076be7e85e75abd00ae Mon Sep 17 00:00:00 2001 From: Matthias Alphart Date: Mon, 15 Mar 2021 15:06:18 +0100 Subject: [PATCH 20/90] remove KNX config_file (#16684) --- source/_integrations/knx.markdown | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/source/_integrations/knx.markdown b/source/_integrations/knx.markdown index 8b0a700733a..11166bcb3c0 100644 --- a/source/_integrations/knx.markdown +++ b/source/_integrations/knx.markdown @@ -80,18 +80,7 @@ knx: Please see the dedicated platform sections below about how to configure them correctly. -Alternatively, if you want to use the [XKNX](https://xknx.io/) library abstraction (e.g., to re-use the configuration also for other scripted tools outside of Home Assistant): - -```yaml -knx: - config_file: "/path/to/xknx.yaml" -``` - {% configuration %} -config_file: - description: The path for XKNX configuration file. See [xknx.io](https://xknx.io/configuration) for details. - required: false - type: string individual_address: description: The KNX individual address (IA) that shall be used for routing or if a tunneling server doesn't assign an IA at connection. required: false From 079549f822e219d508f835c52d02b112e7475b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Mon, 15 Mar 2021 15:09:28 +0100 Subject: [PATCH 21/90] Add weather support to Tado integration (#16096) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- source/_integrations/tado.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/_integrations/tado.markdown b/source/_integrations/tado.markdown index 6018b729ee4..9755b4e7157 100644 --- a/source/_integrations/tado.markdown +++ b/source/_integrations/tado.markdown @@ -8,6 +8,7 @@ ha_category: - Water Heater - Presence Detection - Sensor + - Weather ha_release: 0.41 ha_iot_class: Cloud Polling ha_codeowners: @@ -34,6 +35,7 @@ There is currently support for the following device types within Home Assistant: - Water Heater - for water heater zones. - [Presence Detection](#presence-detection) - Sensor - for some additional information of the zones. +- Weather - for information about the current weather at the location of your Tado home. {% include integrations/config_flow.md %} From ee5fa813a9c9b168a15e1d254c3e818cad66db94 Mon Sep 17 00:00:00 2001 From: starkillerOG Date: Mon, 15 Mar 2021 15:16:12 +0100 Subject: [PATCH 22/90] Add Xiaomi Miio sensor config flow (#16717) --- source/_integrations/xiaomi_miio.markdown | 75 ++--------------------- 1 file changed, 6 insertions(+), 69 deletions(-) diff --git a/source/_integrations/xiaomi_miio.markdown b/source/_integrations/xiaomi_miio.markdown index d7f857e3e01..bbd450fb227 100644 --- a/source/_integrations/xiaomi_miio.markdown +++ b/source/_integrations/xiaomi_miio.markdown @@ -36,8 +36,7 @@ The `xiaomi_miio` integration supports the following devices: - [Xiaomi Gateway](#xiaomi-gateway) - [Xiaomi device tracker (Xiaomi Mi WiFi Repeater 2)](#xiaomi-device-tracker-xiaomi-mi-wifi-repeater-2)) - [Xiaomi Air Purifier and Humidifier](#xiaomi-air-purifier-and-humidifier) -- [Xiaomi Air Quality Index Monitor](#xiaomi-air-quality-index-monitor) -- [Xiaomi Mi Air Quality Monitor](#xiaomi-mi-air-quality-monitor) +- [Xiaomi Air Quality Monitor](#xiaomi-air-quality-monitor) - [Xiaomi IR Remote](#xiaomi-ir-remote) - [Xiaomi Mi Robot Vacuum](#xiaomi-mi-robot-vacuum) - [Xiaomi Philips Light](#xiaomi-philips-light) @@ -869,91 +868,29 @@ Check if the device is in the same subnet as the Home Assistant instance. Otherw If it's not possible to use VLANs for some reason, your last resort may be using NAT translation, between the IPs. -## Xiaomi Air Quality Index Monitor +## Xiaomi Air Quality Monitor -The `xiaomi_miio` sensor platform is observing your Xiaomi Mi Air Quality Monitor (PM2.5) and reporting the air quality index. +The `xiaomi_miio` Air Quality Monitor is observing your Xiaomi Mi Air Quality Monitor (PM2.5) and reporting the air quality index and other values. Currently, the supported features are: - Air Quality Index (AQI) +- Particulate matter 2.5 - Attributes - power - charging - battery - time_stat - -Please follow the instructions on [Retrieving the Access Token](/integrations/xiaomi_miio/#retrieving-the-access-token) to get the API token. - -### Configuration - -To add a Xiaomi Mi Air Quality Monitor to your installation, add the following to your `configuration.yaml` file: - -```yaml -# Example configuration.yaml entry -sensor: - - platform: xiaomi_miio - host: IP_ADDRESS - token: YOUR_TOKEN -``` - -{% configuration %} -host: - description: The IP address of your miio device. - required: true - type: string -token: - description: The API token of your miio device. - required: true - type: string -name: - description: The name of your miio device. - required: false - type: string - default: Xiaomi Miio Sensor -{% endconfiguration %} - -## Xiaomi Mi Air Quality Monitor - -The `xiaomi_miio` sensor platform is observing your Xiaomi Mi Air Quality Monitor and reporting the air quality values. - -Currently, the supported features are: - -- Particulate matter 2.5 -- Attributes - carbon_dioxide_equivalent - total_volatile_organic_compounds - temperature - humidity -Please follow the instructions on [Retrieving the Access Token](/integrations/xiaomi_miio/#retrieving-the-access-token) to get the API token. - ### Configuration -To add a Xiaomi Mi Air Quality Monitor to your installation, add the following to your `configuration.yaml` file: +Please follow the instructions on [Retrieving the Access Token](/integrations/xiaomi_miio/#retrieving-the-access-token) to get the API token to use during configuration flow setup. -```yaml -# Example configuration.yaml entry -air_quality: - - platform: xiaomi_miio - host: IP_ADDRESS - token: YOUR_TOKEN -``` - -{% configuration %} -host: - description: The IP address of your miio device. - required: true - type: string -token: - description: The API token of your miio device. - required: true - type: string -name: - description: The name of your miio device. - required: false - type: string - default: Xiaomi Miio Air Quality Monitor -{% endconfiguration %} +To add a Xiaomi Mi Air Quality Monitor to your installation, click Configuration in the sidebar, then click Integrations and then click the + icon in the lower right and find xiaomi_miio. You will then be presented with a form in which you will need to fill in the “IP address” and 32 characters “token”. After you click submit, you will have the opportunity to select the area that your devices are located. ## Xiaomi IR Remote From 44c4dd69e3f72108a16c5eada62d1b39141088e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Gabriel?= Date: Mon, 15 Mar 2021 11:16:33 -0300 Subject: [PATCH 23/90] Adding Panasonic Viera remote documentation (#15377) Co-authored-by: Franck Nijhof --- source/_integrations/panasonic_viera.markdown | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/source/_integrations/panasonic_viera.markdown b/source/_integrations/panasonic_viera.markdown index b0336fcd781..32cbb39d4e5 100644 --- a/source/_integrations/panasonic_viera.markdown +++ b/source/_integrations/panasonic_viera.markdown @@ -3,6 +3,7 @@ title: Panasonic Viera description: Instructions on how to integrate a Panasonic Viera TV with Home Assistant. ha_category: - Media Player + - Remote ha_release: 0.17 ha_iot_class: Local Polling ha_domain: panasonic_viera @@ -13,9 +14,16 @@ The `panasonic_viera` platform allows you to control a Panasonic Viera TV. {% include integrations/config_flow.md %} +There is currently support for the following device types within Home Assistant: + +- Media Player +- [Remote](#remote) + +{% include integrations/config_flow.md %} + If your TV needs to be paired, you will be prompted to type the PIN code that will be displayed on it. -To allow your TV to be turned on or controlled while off, enable `Powered On By Apps` in the TV Settings: **Network > TV Remote App Settings** +To allow your TV to be turned on or controlled while off, enable `Powered On By Apps` in your settings (if available): **Network > TV Remote App Settings** ## Manual configuration @@ -89,6 +97,23 @@ script: entity_id: media_player.living_room_tv ``` +### Remote + +When the integration is configured, two entities will be created: a `media_player` and a `remote`. The remote allows you to send key commands to your TV with the `remote.send_command` service. + +Some of the known valid key values are: + +- `up` +- `down` +- `left` +- `right` +- `select` +- `home` +- `back` +- `power` + +The list with all known valid keys can be found [here](https://github.com/florianholzapfel/panasonic-viera/blob/521cefadc8e1543514ce41d3d49e9218d1c2302d/panasonic_viera/__init__.py#L35). Additionally, you can also send custom commands, such as `"NRC_HOME-ONOFF"` (which is the same as `home`). + ### Currently known supported models - TC-P50ST50 From 40dda044b51b17fa2d046ac681ec73fa705bc448 Mon Sep 17 00:00:00 2001 From: starkillerOG Date: Mon, 15 Mar 2021 15:32:08 +0100 Subject: [PATCH 24/90] Add Xiaomi Miio Light config flow (#16782) --- source/_integrations/xiaomi_miio.markdown | 40 ++++------------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/source/_integrations/xiaomi_miio.markdown b/source/_integrations/xiaomi_miio.markdown index bbd450fb227..1d803b56364 100644 --- a/source/_integrations/xiaomi_miio.markdown +++ b/source/_integrations/xiaomi_miio.markdown @@ -1410,6 +1410,12 @@ It seems to be the case that Numbers 1..15 are used to number the intitial segme The `xiaomi_miio` platform allows you to control the state of your Xiaomi Philips LED Ball Lamp, Xiaomi Philips Zhirui LED Bulb E14 Candle Lamp, Xiaomi Philips Zhirui Downlight, Xiaomi Philips LED Ceiling Lamp, Xiaomi Philips Eyecare Lamp 2, Xiaomi Philips Moonlight Bedside Lamp and Philips Zhirui Desk Lamp. +Please follow the instructions on [Retrieving the Access Token](/integrations/xiaomi_miio/#retrieving-the-access-token) to get the API token to use during configuration flow setup. + +### Configuration + +To add a Xiaomi Philips Light to your installation, click Configuration in the sidebar, then click Integrations and then click the + icon in the lower right and find xiaomi_miio. You will then be presented with a form in which you will need to fill in the “IP address” and 32 characters “token”. After you click submit, you will have the opportunity to select the area that your devices are located. + ### Features ### Philips LED Ball Lamp, Philips Zhirui LED Candle Lamp and Philips Zhirui Downlight @@ -1494,40 +1500,6 @@ Supported models: `philips.light.moonlight` - brand_sleep - brand -Please follow the instructions on [Retrieving the Access Token](/integrations/xiaomi_miio/#retrieving-the-access-token) to get the API token to use in the `configuration.yaml` file. - -To add a Xiaomi Philips Light to your installation, add the following to your `configuration.yaml` file: - -```yaml -# Example configuration.yaml entries -light: - - platform: xiaomi_miio - name: Xiaomi Philips Smart LED Ball - host: 192.168.130.67 - token: YOUR_TOKEN - model: philips.light.bulb -``` - -{% configuration %} -host: - description: The IP address of your miio light. - required: true - type: string -token: - description: The API token of your miio light. - required: true - type: string -name: - description: The name of your miio light. - required: false - type: string - default: Xiaomi Philips Light -model: - description: The model of your light. Valid values are `philips.light.sread1`, `philips.light.ceiling`, `philips.light.zyceiling`, `philips.light.moonlight`, `philips.light.bulb`, `philips.light.candle`, `philips.light.candle2`, `philips.light.mono1` and `philips.light.downlight`. This setting can be used to bypass the device model detection and is recommended if your device isn't always available. - required: false - type: string -{% endconfiguration %} - ### Platform Services ### Service `xiaomi_miio.light_set_scene` From 9781bca09d8a11d06ed0f8208b9320b1e5de1dfe Mon Sep 17 00:00:00 2001 From: starkillerOG Date: Mon, 15 Mar 2021 15:32:28 +0100 Subject: [PATCH 25/90] Add subdevice lightbulb support (#16619) --- source/_integrations/xiaomi_miio.markdown | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/_integrations/xiaomi_miio.markdown b/source/_integrations/xiaomi_miio.markdown index 1d803b56364..b3daac0be6f 100644 --- a/source/_integrations/xiaomi_miio.markdown +++ b/source/_integrations/xiaomi_miio.markdown @@ -238,6 +238,14 @@ These subdevices are fully implemented in HomeAssistant: | -------------------------------- | ----------------------- | --------------- | ------------------------------------------------ | | Weather sensor | lumi.sensor_ht | WSDCGQ01LM | readout `temperature` and `humidity` | | Weather sensor | lumi.weather.v1 | WSDCGQ11LM | readout `temperature`, `humidity` and `pressure` | +| Smart bulb E27 | lumi.light.aqcn02 | ZNLDP12LM | on/off, brightness, color temperature | +| IKEA smart bulb E27 white | ikea.light.led1545g12 | LED1545G12 | on/off, brightness, color temperature | +| IKEA smart bulb E27 white | ikea.light.led1546g12 | LED1546G12 | on/off, brightness, color temperature | +| IKEA smart bulb E12 white | ikea.light.led1536g5 | LED1536G5 | on/off, brightness, color temperature | +| IKEA smart bulb GU10 white | ikea.light.led1537r6 | LED1537R6 | on/off, brightness, color temperature | +| IKEA smart bulb E27 white | ikea.light.led1623g12 | LED1623G12 | on/off, brightness, color temperature | +| IKEA smart bulb GU10 white | ikea.light.led1650r5 | LED1650R5 | on/off, brightness, color temperature | +| IKEA smart bulb E12 white | ikea.light.led1649c5 | LED1649C5 | on/off, brightness, color temperature | ### Recognized subdevices (not yet implemented) @@ -284,14 +292,6 @@ These subdevices are recognized by the python-miio code but are still being work | Door lock S2 | lumi.lock.acn02 | ZNMS12LM | | Door lock S2 pro | lumi.lock.acn03 | ZNMS13LM | | Vima cylinder lock | lumi.lock.v1 | A6121 | -| Smart bulb E27 | lumi.light.aqcn02 | ZNLDP12LM | -| IKEA smart bulb E27 white | ikea.light.led1545g12 | LED1545G12 | -| IKEA smart bulb E27 white | ikea.light.led1546g12 | LED1546G12 | -| IKEA smart bulb E12 white | ikea.light.led1536g5 | LED1536G5 | -| IKEA smart bulb GU10 white | ikea.light.led1537r6 | LED1537R6 | -| IKEA smart bulb E27 white | ikea.light.led1623g12 | LED1623G12 | -| IKEA smart bulb GU10 white | ikea.light.led1650r5 | LED1650R5 | -| IKEA smart bulb E12 white | ikea.light.led1649c5 | LED1649C5 | | Thermostat S2 | lumi.airrtc.tcpecn02 | KTWKQ03ES | ## Xiaomi device tracker (Xiaomi Mi WiFi Repeater 2) From 2f3481e6c2cde7e5bbdc47db80c70dae519182be Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Mon, 15 Mar 2021 15:33:58 +0100 Subject: [PATCH 26/90] Add apply_filter to recorder.purge service (#16377) --- source/_integrations/recorder.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/source/_integrations/recorder.markdown b/source/_integrations/recorder.markdown index 00b7d16ef67..a50954ad7be 100644 --- a/source/_integrations/recorder.markdown +++ b/source/_integrations/recorder.markdown @@ -210,6 +210,7 @@ Note that purging will not immediately decrease disk space usage but it will sig | ---------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `keep_days` | yes | The number of history days to keep in recorder database (defaults to the integration `purge_keep_days` configuration) | | `repack` | yes | When using SQLite or PostgreSQL this will rewrite the entire database. When using MySQL or MariaDB it will optimize or recreate the events and states tables. This is a heavy operation that can cause slowdowns and increased disk space usage while it runs. Only supported by SQLite, PostgreSQL, MySQL and MariaDB. | +| `apply_filter` | yes | Apply entity_id and event_type filter in addition to time based purge. Useful in combination with `include` / `exclude` filter to remove falsely added states and events. Combine with `repack: true` to reduce database size. | ### Service `disable` From 2fa97ec08c0fb8a2b99e4c258af4752422805f21 Mon Sep 17 00:00:00 2001 From: Khole Date: Mon, 15 Mar 2021 14:35:06 +0000 Subject: [PATCH 27/90] Hive UI Docs update (#16568) Co-authored-by: Franck Nijhof --- source/_integrations/hive.markdown | 33 ++++++++---------------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/source/_integrations/hive.markdown b/source/_integrations/hive.markdown index b66db5a8470..47e9b5b6c75 100644 --- a/source/_integrations/hive.markdown +++ b/source/_integrations/hive.markdown @@ -24,35 +24,20 @@ ha_platforms: - water_heater --- -The `hive` integration is the main integration to set up and integrate all supported Hive devices. Once configured with the minimum required details it will detect and add all Hive devices into Home Assistant, including support for multi-zone heating. +The Hive integration for Home Assistant allows you to interact with supported devices and services offered by +[hivehome.com](https://www.hivehome.com) -This integration uses the Hive website [https://my.hivehome.com](https://my.hivehome.com) credentials, you will need to use the same username and password you use on the Hive website to configure this Hive integration in Home Assistant. +This Hive integration uses the same username and password you use on the [Hive website](https://sso.hivehome.com) to configure it within Home Assistant, 2FA authentication is also supported. Once configured Home Assistant will detect and add all Hive devices, including support for multi-zone heating. -To add your Hive devices into your Home Assistant installation, add the following to your `configuration.yaml` file: +{% include integrations/config_flow.md %} -```yaml -# Example configuration.yaml entry -hive: - username: YOUR_USERNAME - password: YOUR_PASSWORD -``` -{% configuration %} -username: - description: Your username from [https://my.hivehome.com](https://my.hivehome.com). - required: true - type: string -password: - description: Your password from [https://my.hivehome.com](https://my.hivehome.com). - required: true - type: string -scan_interval: - description: The time in minutes between Hive API calls - required: false - type: integer - default: 2 -{% endconfiguration %} +## Options +Menu: *Configuration* > *Integrations* > *Select your new integration* > *Press the options button* + +- **Scan Interval**: Update the scan interval allowing the integration to poll for data more frequently (Cannot be set lower than 30 seconds). + ## Services ### Service `hive.boost_heating` From ce5b32d348050afdf51efd68ce15640529c4b92b Mon Sep 17 00:00:00 2001 From: starkillerOG Date: Mon, 15 Mar 2021 15:41:27 +0100 Subject: [PATCH 28/90] Add gateway switch support (#16617) --- source/_integrations/xiaomi_miio.markdown | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/_integrations/xiaomi_miio.markdown b/source/_integrations/xiaomi_miio.markdown index b3daac0be6f..97e5f66555a 100644 --- a/source/_integrations/xiaomi_miio.markdown +++ b/source/_integrations/xiaomi_miio.markdown @@ -238,6 +238,18 @@ These subdevices are fully implemented in HomeAssistant: | -------------------------------- | ----------------------- | --------------- | ------------------------------------------------ | | Weather sensor | lumi.sensor_ht | WSDCGQ01LM | readout `temperature` and `humidity` | | Weather sensor | lumi.weather.v1 | WSDCGQ11LM | readout `temperature`, `humidity` and `pressure` | +| Wall switch single | lumi.ctrl_ln1 | QBKG11LM | load_power, status, turn_on, turn_off, toggle | +| Wall switch single | lumi.ctrl_ln1.aq1 | QBKG11LM | load_power, status, turn_on, turn_off, toggle | +| Wall switch no neutral | lumi.ctrl_neutral1.v1 | QBKG04LM | status, turn_on, turn_off, toggle | +| Wall switch double | lumi.ctrl_ln2 | QBKG12LM | load_power, status, turn_on, turn_off, toggle | +| Wall switch double | lumi.ctrl_ln2.aq1 | QBKG12LM | load_power, status, turn_on, turn_off, toggle | +| Wall switch double no neutral | lumi.ctrl_neutral2 | QBKG03LM | status, turn_on, turn_off, toggle | +| D1 wall switch triple | lumi.switch.n3acn3 | QBKG26LM | load_power, status, turn_on, turn_off, toggle | +| D1 wall switch triple no neutral | lumi.switch.l3acn3 | QBKG25LM | load_power, status, turn_on, turn_off, toggle | +| Wall outlet | lumi.ctrl_86plug.v1 | QBCZ11LM | status, turn_on, turn_off, toggle | +| Wall outlet | lumi.ctrl_86plug.aq1 | QBCZ11LM | load_power, status, turn_on, turn_off, toggle | +| Plug | lumi.plug | ZNCZ02LM | load_power, status, turn_on, turn_off, toggle | +| Relay | lumi.relay.c2acn01 | LLKZMK11LM | load_power, status, turn_on, turn_off, toggle | | Smart bulb E27 | lumi.light.aqcn02 | ZNLDP12LM | on/off, brightness, color temperature | | IKEA smart bulb E27 white | ikea.light.led1545g12 | LED1545G12 | on/off, brightness, color temperature | | IKEA smart bulb E27 white | ikea.light.led1546g12 | LED1546G12 | on/off, brightness, color temperature | @@ -273,18 +285,6 @@ These subdevices are recognized by the python-miio code but are still being work | Remote switch double | lumi.sensor_86sw2.v1 | WXKG02LM 2016 | | Remote switch double | lumi.remote.b286acn01 | WXKG02LM 2018 | | D1 remote switch double | lumi.remote.b286acn02 | WXKG07LM | -| Wall switch single | lumi.ctrl_ln1 | QBKG11LM | -| Wall switch single | lumi.ctrl_ln1.aq1 | QBKG11LM | -| Wall switch no neutral | lumi.ctrl_neutral1.v1 | QBKG04LM | -| Wall switch double | lumi.ctrl_ln2 | QBKG12LM | -| Wall switch double | lumi.ctrl_ln2.aq1 | QBKG12LM | -| Wall switch double no neutral | lumi.ctrl_neutral2 | QBKG03LM | -| D1 wall switch triple | lumi.switch.n3acn3 | QBKG26LM | -| D1 wall switch triple no neutral | lumi.switch.l3acn3 | QBKG25LM | -| Wall outlet | lumi.ctrl_86plug.v1 | QBCZ11LM | -| Wall outlet | lumi.ctrl_86plug.aq1 | QBCZ11LM | -| Plug | lumi.plug | ZNCZ02LM | -| Relay | lumi.relay.c2acn01 | LLKZMK11LM | | Curtain | lumi.curtain | ZNCLDJ11LM | | Curtain | lumi.curtain.aq2 | ZNGZDJ11LM | | Curtain B1 | lumi.curtain.hagl04 | ZNCLDJ12LM | From 8033cf271288a5a283f4bdbbc055fb91fe2e8f76 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 15 Mar 2021 16:26:08 +0100 Subject: [PATCH 29/90] Remove duplicate configuration instruction from Panasonic Viera (#17014) --- source/_integrations/panasonic_viera.markdown | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/_integrations/panasonic_viera.markdown b/source/_integrations/panasonic_viera.markdown index 32cbb39d4e5..6614b86464c 100644 --- a/source/_integrations/panasonic_viera.markdown +++ b/source/_integrations/panasonic_viera.markdown @@ -12,8 +12,6 @@ ha_config_flow: true The `panasonic_viera` platform allows you to control a Panasonic Viera TV. -{% include integrations/config_flow.md %} - There is currently support for the following device types within Home Assistant: - Media Player From 0311c161d54c282e7e13de8396c40cf3ec664aa1 Mon Sep 17 00:00:00 2001 From: Nathan Tilley Date: Mon, 15 Mar 2021 11:20:55 -0500 Subject: [PATCH 30/90] Update WOL Documentation For Bugfix (#16946) --- source/_integrations/wake_on_lan.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_integrations/wake_on_lan.markdown b/source/_integrations/wake_on_lan.markdown index f77761accaa..31e1c48fe88 100644 --- a/source/_integrations/wake_on_lan.markdown +++ b/source/_integrations/wake_on_lan.markdown @@ -83,7 +83,7 @@ name: default: Wake on LAN type: string host: - description: The IP address or hostname to check the state of the device (on/off). + description: The IP address or hostname to check the state of the device (on/off). If this is not provided, the state of the switch will be assumed based on the last action that was taken. required: false type: string turn_off: From 968bb0eb17a4e7d53e97ef2d20b9995f0d96f4d3 Mon Sep 17 00:00:00 2001 From: RadekHvizdos <10856567+RadekHvizdos@users.noreply.github.com> Date: Mon, 15 Mar 2021 20:13:56 +0100 Subject: [PATCH 31/90] Update documentation MQTT suggested_area (#17003) Add MQTT suggested_area to the documentation (next branch) --- source/_docs/mqtt/discovery.markdown | 1 + source/_integrations/alarm_control_panel.mqtt.markdown | 4 ++++ source/_integrations/binary_sensor.mqtt.markdown | 4 ++++ source/_integrations/camera.mqtt.markdown | 4 ++++ source/_integrations/climate.mqtt.markdown | 4 ++++ source/_integrations/cover.mqtt.markdown | 4 ++++ source/_integrations/device_tracker.mqtt.markdown | 4 ++++ source/_integrations/device_trigger.mqtt.markdown | 4 ++++ source/_integrations/fan.mqtt.markdown | 4 ++++ source/_integrations/light.mqtt.markdown | 4 ++++ source/_integrations/lock.mqtt.markdown | 4 ++++ source/_integrations/sensor.mqtt.markdown | 4 ++++ source/_integrations/switch.mqtt.markdown | 4 ++++ source/_integrations/tag.mqtt.markdown | 4 ++++ source/_integrations/vacuum.mqtt.markdown | 4 ++++ 15 files changed, 57 insertions(+) diff --git a/source/_docs/mqtt/discovery.markdown b/source/_docs/mqtt/discovery.markdown index bd40db3fe5b..3a057e6f930 100644 --- a/source/_docs/mqtt/discovery.markdown +++ b/source/_docs/mqtt/discovery.markdown @@ -273,6 +273,7 @@ Supported abbreviations for device registry configuration: 'mf': 'manufacturer', 'mdl': 'model', 'sw': 'sw_version', + 'sa': 'suggested_area', ``` ## Support by third-party tools diff --git a/source/_integrations/alarm_control_panel.mqtt.markdown b/source/_integrations/alarm_control_panel.mqtt.markdown index 4d7647c9e38..895ba5364fe 100644 --- a/source/_integrations/alarm_control_panel.mqtt.markdown +++ b/source/_integrations/alarm_control_panel.mqtt.markdown @@ -113,6 +113,10 @@ device: description: "The name of the device." required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: "The firmware version of the device." required: false diff --git a/source/_integrations/binary_sensor.mqtt.markdown b/source/_integrations/binary_sensor.mqtt.markdown index 428f376dfaf..be94a14381c 100644 --- a/source/_integrations/binary_sensor.mqtt.markdown +++ b/source/_integrations/binary_sensor.mqtt.markdown @@ -84,6 +84,10 @@ device: description: The name of the device. required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: The firmware version of the device. required: false diff --git a/source/_integrations/camera.mqtt.markdown b/source/_integrations/camera.mqtt.markdown index 811382e65a4..80fd9f0796a 100644 --- a/source/_integrations/camera.mqtt.markdown +++ b/source/_integrations/camera.mqtt.markdown @@ -77,6 +77,10 @@ device: description: The name of the device. required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: The firmware version of the device. required: false diff --git a/source/_integrations/climate.mqtt.markdown b/source/_integrations/climate.mqtt.markdown index 448ac310a3c..373ae3b2a8b 100644 --- a/source/_integrations/climate.mqtt.markdown +++ b/source/_integrations/climate.mqtt.markdown @@ -116,6 +116,10 @@ device: description: 'The name of the device.' required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: 'The firmware version of the device.' required: false diff --git a/source/_integrations/cover.mqtt.markdown b/source/_integrations/cover.mqtt.markdown index 8bf363c6710..0d72e73249b 100644 --- a/source/_integrations/cover.mqtt.markdown +++ b/source/_integrations/cover.mqtt.markdown @@ -94,6 +94,10 @@ device: description: The name of the device. required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: The firmware version of the device. required: false diff --git a/source/_integrations/device_tracker.mqtt.markdown b/source/_integrations/device_tracker.mqtt.markdown index 1c777d8f7a6..33eda93ed90 100644 --- a/source/_integrations/device_tracker.mqtt.markdown +++ b/source/_integrations/device_tracker.mqtt.markdown @@ -133,6 +133,10 @@ device: description: The name of the device. required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: The firmware version of the device. required: false diff --git a/source/_integrations/device_trigger.mqtt.markdown b/source/_integrations/device_trigger.mqtt.markdown index 1f47e3f0fe6..f088a7cbe68 100644 --- a/source/_integrations/device_trigger.mqtt.markdown +++ b/source/_integrations/device_trigger.mqtt.markdown @@ -68,6 +68,10 @@ device: description: The name of the device. required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: The firmware version of the device. required: false diff --git a/source/_integrations/fan.mqtt.markdown b/source/_integrations/fan.mqtt.markdown index cd43ae5c1ad..bd53656f198 100644 --- a/source/_integrations/fan.mqtt.markdown +++ b/source/_integrations/fan.mqtt.markdown @@ -85,6 +85,10 @@ device: description: The name of the device. required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: The firmware version of the device. required: false diff --git a/source/_integrations/light.mqtt.markdown b/source/_integrations/light.mqtt.markdown index 8f833fbe3b2..549cd01e1d1 100644 --- a/source/_integrations/light.mqtt.markdown +++ b/source/_integrations/light.mqtt.markdown @@ -138,6 +138,10 @@ device: description: 'The name of the device.' required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: 'The firmware version of the device.' required: false diff --git a/source/_integrations/lock.mqtt.markdown b/source/_integrations/lock.mqtt.markdown index 08beb2e43ae..1cb52e8d396 100644 --- a/source/_integrations/lock.mqtt.markdown +++ b/source/_integrations/lock.mqtt.markdown @@ -85,6 +85,10 @@ device: description: 'The name of the device.' required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: 'The firmware version of the device.' required: false diff --git a/source/_integrations/sensor.mqtt.markdown b/source/_integrations/sensor.mqtt.markdown index f0d2dc8391b..e082f81f8c0 100644 --- a/source/_integrations/sensor.mqtt.markdown +++ b/source/_integrations/sensor.mqtt.markdown @@ -75,6 +75,10 @@ device: description: The name of the device. required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: The firmware version of the device. required: false diff --git a/source/_integrations/switch.mqtt.markdown b/source/_integrations/switch.mqtt.markdown index 4ad3ee8f93e..59f51b21c29 100644 --- a/source/_integrations/switch.mqtt.markdown +++ b/source/_integrations/switch.mqtt.markdown @@ -85,6 +85,10 @@ device: description: The name of the device. required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: The firmware version of the device. required: false diff --git a/source/_integrations/tag.mqtt.markdown b/source/_integrations/tag.mqtt.markdown index 1fba648a745..1b509fd1efd 100644 --- a/source/_integrations/tag.mqtt.markdown +++ b/source/_integrations/tag.mqtt.markdown @@ -49,6 +49,10 @@ device: description: The name of the device. required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: The firmware version of the device. required: false diff --git a/source/_integrations/vacuum.mqtt.markdown b/source/_integrations/vacuum.mqtt.markdown index 60323b25f3b..2bc77dff3be 100644 --- a/source/_integrations/vacuum.mqtt.markdown +++ b/source/_integrations/vacuum.mqtt.markdown @@ -348,6 +348,10 @@ device: description: The name of the device. required: false type: string + suggested_area: + description: 'Suggest an area if the device isn’t in one yet.' + required: false + type: string sw_version: description: The firmware version of the device. required: false From ff80b77bbd955890c1ffd04a6067b553019aa5ad Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 16 Mar 2021 00:47:15 +0100 Subject: [PATCH 32/90] Add config flow to Verisure (#17000) --- source/_integrations/verisure.markdown | 72 ++------------------------ 1 file changed, 3 insertions(+), 69 deletions(-) diff --git a/source/_integrations/verisure.markdown b/source/_integrations/verisure.markdown index 97a90b73d59..c2e002ab1a4 100644 --- a/source/_integrations/verisure.markdown +++ b/source/_integrations/verisure.markdown @@ -21,6 +21,8 @@ ha_platforms: - lock - sensor - switch +ha_config_flow: true +ha_dhcp: true --- Home Assistant has support to integrate your [Verisure](https://www.verisure.com/) devices. @@ -34,75 +36,7 @@ There is currently support for the following device types within Home Assistant: - Lock - Binary Sensor (Door & Window) -## Configuration - -To integrate Verisure with Home Assistant, add the following section to your `configuration.yaml` file: - -```yaml -# Example configuration.yaml entry -verisure: - username: USERNAME - password: PASSWORD -``` - -{% configuration %} -username: - description: The username to Verisure mypages. - required: true - type: string -password: - description: The password to Verisure mypages. - required: true - type: string -alarm: - description: Set to `true` to show alarm, `false` to disable. - required: false - type: boolean - default: true -hygrometers: - description: Set to `true` to show hygrometers, `false` to disable. - required: false - type: boolean - default: true -smartplugs: - description: Set to `true` to show smartplugs, `false` to disable. - required: false - type: boolean - default: true -locks: - description: Set to `true` to show locks, `false` to disable. - required: false - type: boolean - default: true -default_lock_code: - description: Code that will be used to lock or unlock, if none is supplied. - required: false - type: string -thermometers: - description: Set to `true` to show thermometers, `false` to disable. - required: false - type: boolean - default: true -mouse: - description: Set to `true` to show mouse detectors, `false` to disable. - required: false - type: boolean - default: true -door_window: - description: Set to `true` to show doors and windows, `false` to disable. - required: false - type: boolean - default: true -code_digits: - description: Number of digits in PIN code. - required: false - type: integer - default: 4 -giid: - description: The GIID of your installation (If you have more then one alarm system). To find the GIID for your systems run `python verisure.py` EMAIL PASSWORD installations'. - required: false - type: string -{% endconfiguration %} +{% include integrations/config_flow.md %} ## Alarm Control Panel From 173875f77ce21a66e65dfa83aab2a287242bf70f Mon Sep 17 00:00:00 2001 From: Kevin Worrel <37058192+dieselrabbit@users.noreply.github.com> Date: Tue, 16 Mar 2021 16:32:17 -0700 Subject: [PATCH 33/90] Add screenlogic integration documentation (#17010) Add documentation for Pentair ScreenLogic integration. --- source/_integrations/screenlogic.markdown | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 source/_integrations/screenlogic.markdown diff --git a/source/_integrations/screenlogic.markdown b/source/_integrations/screenlogic.markdown new file mode 100644 index 00000000000..be182dacf94 --- /dev/null +++ b/source/_integrations/screenlogic.markdown @@ -0,0 +1,33 @@ +--- +title: "Pentair ScreenLogic" +description: "Instructions on how to integrate a ScreenLogic gateway within Home Assistant." +ha_release: "2021.4" +ha_category: + - Hub + - Sensor + - Binary Sensor + - Switch + - Water Heater +ha_iot_class: "Local Polling" +ha_quality_scale: gold +ha_config_flow: true +ha_dhcp: true +ha_codeowners: + - '@dieselrabbit' +ha_domain: screenlogic +ha_platforms: + - switch + - binary_sensor + - sensor + - water_heater +--- + +The Pentair ScreenLogic integration allows you to integrate your Pentair Intellitouch or EasyTouch pool controller with Home Assistant via the [Pentair ScreenLogic](https://www.pentair.com/en-us/products/residential/pool-spa-equipment/pool-automation/screenlogic2_interfaceforintellitouchandeasytouchautomationsystems.html) gateway. + +{% include integrations/config_flow.md %} + +## Options + +ScreenLogic options are set via **Configuration** -> **Integrations** -> **Pentair ScreenLogic** -> **Options**. + +* Seconds between scans - How many seconds between each polling of the ScreenLogic gateway. From 85f265312783881988427de18113984d5847a495 Mon Sep 17 00:00:00 2001 From: Andreas <28764847+andreas-amlabs@users.noreply.github.com> Date: Thu, 18 Mar 2021 12:42:59 +0100 Subject: [PATCH 34/90] Amcrest add documentation for CrossLineDetected (#16033) Co-authored-by: andreas-amlabs --- source/_integrations/amcrest.markdown | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/_integrations/amcrest.markdown b/source/_integrations/amcrest.markdown index 1c266a8d6ff..fd642957a8d 100644 --- a/source/_integrations/amcrest.markdown +++ b/source/_integrations/amcrest.markdown @@ -117,6 +117,10 @@ binary_sensors: description: "Return `on` when a motion is detected, `off` when not. Motion detection is enabled by default for most cameras, if this functionality is not working check that it is enabled in Settings > Events > Video Detection. Uses streaming method (see [below](#streaming-vs-polled-binary-sensors))." motion_detected_polled: description: "Return `on` when a motion is detected, `off` when not. Motion detection is enabled by default for most cameras, if this functionality is not working check that it is enabled in Settings > Events > Video Detection. Uses polled method (see [below](#streaming-vs-polled-binary-sensors))." + crossline_detected: + description: "Return `on` when a tripwire tripping is detected, `off` when not. Uses streaming method (see [below](#streaming-vs-polled-binary-sensors))." + crossline_detected_polled: + description: "Return `on` when a tripwire is tripping is detected, `off` when not. Uses polled method (see [below](#streaming-vs-polled-binary-sensors))." online: description: "Return `on` when camera is available (i.e., responding to commands), `off` when not." sensors: @@ -377,6 +381,7 @@ amcrest: password: YOUR_PASSWORD binary_sensors: - motion_detected + - crossline_detected - online sensors: - sdcard From f00dd8f833aebe8cd5f30cbef27356deddaec28a Mon Sep 17 00:00:00 2001 From: elyobelyob Date: Thu, 18 Mar 2021 18:27:26 +0000 Subject: [PATCH 35/90] Url option (#17026) --- source/_integrations/prowl.markdown | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/_integrations/prowl.markdown b/source/_integrations/prowl.markdown index f9ce195bdb3..ea7e84b83e6 100644 --- a/source/_integrations/prowl.markdown +++ b/source/_integrations/prowl.markdown @@ -40,8 +40,9 @@ api_key: The following attributes can be placed `data` for extended functionality. -| Service data attribute | Optional | Description | -| ---------------------- | -------- | ----------- | -| `priority` | yes | Priority level, for more info refer to the [Prowl API documentation](https://www.prowlapp.com/api.php#add). | +| Service data attribute | Optional | Default | Description | +| ---------------------- | -------- | ------- | ----------- | +| `priority` | yes | 0 | Priority level, for more info refer to the [Prowl API documentation](https://www.prowlapp.com/api.php#add). | +| `url` | yes | n/a | URL to be attached, for more info refer to the [Prowl API documentation](https://www.prowlapp.com/api.php#add). | To use notifications, please see the [getting started with automation page](/getting-started/automation/). From 74c562332388e4a68665f7a6d4a4f47871af0233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Kr=C3=B6ner?= Date: Fri, 19 Mar 2021 19:53:44 +0100 Subject: [PATCH 36/90] Update documentation for the OpenWeatherMap integration (#17060) --- source/_integrations/openweathermap.markdown | 68 ++++++++++++++------ 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/source/_integrations/openweathermap.markdown b/source/_integrations/openweathermap.markdown index edd7e5aa66f..445062bffbb 100644 --- a/source/_integrations/openweathermap.markdown +++ b/source/_integrations/openweathermap.markdown @@ -37,35 +37,61 @@ You need an API key, which is free, but requires a [registration](https://home.o | Mode | Forecast mode, `hourly` for a three-hour forecast, `daily` for daily forecast using a paid API tier, `onecall_hourly` for an hourly forecast up to 2 days, or `onecall_daily` for a daily forecast up to 7 days (ideal for the free tier). | | Language | Language for receiving data (only for `sensor`) | -The integration creates weather entity and also sensors for all available conditions. -Selecting a `onecall` mode with the free tier leverages the One Call API, resulting in updates every 5 minutes and is recommended for both hourly and daily forecast. +The integration creates a weather entity as well as sensors for supported weather conditions. +Selecting a `onecall` forecast mode with the free tier leverages the One Call API, resulting in updates every 5 minutes and is recommended for both hourly and daily forecast. -For each condition `sensor` entity will be created with id: +A `sensor` entity will be created for each supported condition. Their ids will follow the format: `sensor._` -Sensor prints information in language which was selected for integration. - -All conditions: - -| Condition | Description | -| :------------- | :----------------------------------- | -| `weather` | A human-readable text summary. | -| `temperature` | Current temperature. | -| `wind_speed` | Wind speed. | -| `wind_bearing` | Wind bearing. | -| `humidity` | Relative humidity. | -| `pressure` | Sea-level air pressure in millibars. | -| `clouds` | Description of cloud coverage. | -| `rain` | Rain volume. | -| `snow` | Snow volume. | -| `condition` | Current weather condition code. | -| `weather_code` | Current weather code. | +Sensors provide data in the language that was selected when configuring the integration.
    -Weather entity always will have English language. Home Assistant translate it to user language automatically. +The Weather entity provides data only in English. Home Assistant automatically translates it to the language configured for the frontend.
    +## Supported Weather Conditions + +### Current Weather Conditions + +| Condition | Description | +| :----------------------- | :------------------------------------------------------------------------------------------------------------------------------ | +| `cloud_coverage` | Cloudiness, %. | +| `condition` | [Weather condition](https://developers.home-assistant.io/docs/core/entity/weather/#recommended-values-for-state-and-condition). | +| `dew_point` | Atmospheric temperature below which water droplets begin to condense and dew can form, ºC. | +| `feels_like_temperature` | Temperature accounting for the human perception of weather, ºC. | +| `humidity` | Humidity, %. | +| `precipitation_kind` | The kind of precipitation (Rain, Snow, Snow and Rain, None) for the last hour. | +| `pressure` | Atmospheric pressure at sea level, hPa. | +| `rain` | Rain volume for the last hour, mm. | +| `snow` | Snow volume for the last hour, mm. | +| `temperature` | Temperature, ºC. | +| `uv_index` | UV Index. | +| `weather` | A human-readable description of the [weather condition](https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2). | +| `weather_code` | ID of the [weather condition](https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2). | +| `wind_bearing` | Wind direction, degrees (meteorological). | +| `wind_speed` | Wind speed, metre/sec. | + +### Forecast Weather Conditions + +
    + +The time period these sensors use depends on the forecast mode selected when configuring the integration: `hourly` or `onecall_hourly` will show conditions for the current hour of the day, while `daily` or `onecall_daily` will show conditions for the current day. + +
    + +| Condition | Description | +| :----------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `forecast_condition` | [Weather condition](https://developers.home-assistant.io/docs/core/entity/weather/#recommended-values-for-state-and-condition) for the forecast's time period. | +| `forecast_precipitation` | Combined Rain and Snow volume for the forecast's time period, mm. | +| `forecast_precipitation_probability` | Probability of precipitation for the forecast's time period. | +| `forecast_pressure` | Atmospheric pressure at sea level for the forecast's time period, hPa. | +| `forecast_temperature` | Maximum temperature for the day. | +| `forecast_temperature_low` | Minimum temperature for the day. | +| `forecast_time` | Time of the forecasted data. | +| `forecast_wind_bearing` | Wind direction for the forecast's time period, degrees (meteorological). | +| `forecast_wind_speed` | Wind speed for the forecast's time period, metre/sec. | + Details about the API are available in the [OpenWeatherMap documentation](https://openweathermap.org/api). From bd4da144858c063be8b3c6b9600d85fe76144e02 Mon Sep 17 00:00:00 2001 From: Antoine Meillet Date: Fri, 19 Mar 2021 21:41:28 +0100 Subject: [PATCH 37/90] Add details about unavailable and unknown states for Prometheus (#17039) Co-authored-by: Franck Nijhof --- source/_integrations/prometheus.markdown | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/_integrations/prometheus.markdown b/source/_integrations/prometheus.markdown index b7b7623abe2..3e541e0aa0b 100644 --- a/source/_integrations/prometheus.markdown +++ b/source/_integrations/prometheus.markdown @@ -179,3 +179,16 @@ When looking into the metrics on the Prometheus side, there will be: - The [client library](https://github.com/prometheus/client_python) provided metrics, which are a bunch of **process_\*** and also a single pseudo-metric **python_info** which contains (not as value but as labels) information about the Python version of the client, i.e., the Home Assistant Python interpreter. Typically, you will only be interested in the first set of metrics. + +## Metrics in unavailable or unknown states + +When the Prometheus exporter starts (typically when Home Assistant starts), all non-excluded entities in an unavailable or unknown state are not be exported until they are available again. If the entity goes into state unavailable or unknown again, the value exported will always be the latest known one. + +While an entity is in those states, the `entity_available` corresponding metric is set to 0. This metric can be used to filter out values while the entity is unavailable or in an unknown state thanks to a [recording rule](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/). + +For example: + +```yaml +- record: "known_temperature_c" + expr: "temperature_c unless entity_available == 0" +``` From 5dd8aea9b0e960fc5f4cb6babe9466ed94257041 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 19 Mar 2021 15:42:43 -0500 Subject: [PATCH 38/90] Add homeassistant.reload_config_entry service (#16976) --- source/_integrations/homeassistant.markdown | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/_integrations/homeassistant.markdown b/source/_integrations/homeassistant.markdown index cd242cb82ac..1b2768f2e33 100644 --- a/source/_integrations/homeassistant.markdown +++ b/source/_integrations/homeassistant.markdown @@ -21,6 +21,16 @@ The `homeassistant` integration provides services for controlling Home Assistant Reads the configuration files and checks them for correctness, but **does not** load them into Home Assistant. Creates a persistent notification and log entry if errors are found. +### Service `homeassistant.reload_config_entry` + +Reloads an integration config entry. + +| Service data attribute | Description | +|---------------------------|-------------------------------------------------------| +| `entity_id` | List of entity ids used to reference a config entry. | +| `area_id` | List of area ids used to reference a config entry. | +| `device_id` | List of device ids used to reference a config entry. | + ### Service `homeassistant.reload_core_config` Reloads the core configuration under `homeassistant:` and all linked files. Once loaded the new configuration is applied. New `customize:` information will be applied the next time the state of the entity gets updated. From ed3cfd06219b2893411d92ebe6686e7e7ad0aae4 Mon Sep 17 00:00:00 2001 From: bestlibre Date: Fri, 19 Mar 2021 22:08:52 +0100 Subject: [PATCH 39/90] Add notification with images example (#13943) Co-authored-by: Franck Nijhof --- source/_integrations/matrix.markdown | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source/_integrations/matrix.markdown b/source/_integrations/matrix.markdown index 9c2bda7d82b..d334d064aec 100644 --- a/source/_integrations/matrix.markdown +++ b/source/_integrations/matrix.markdown @@ -175,3 +175,18 @@ default_room: The target room has to be precreated, the room id can be obtained from the rooms settings dialog. Rooms by default have a canonical id of the form `"!:homeserver.tld"`, but can also be allocated aliases like `"#roomname:homeserver.tld"`. Make sure to use quotes around the room id or alias to escape special characters (`!`, and `#`) in YAML. The notifying account may need to be invited to the room, depending on the individual rooms policies. To use notifications, please see the [getting started with automation page](/getting-started/automation/). + +### Images in notification + +It is possible to send images with notifications. To do so, add a list of paths in the notification `data`. + +```yaml +# Example of notification with images +action: + service: notify.matrix_notify + data: + message: "Test with images" + data: + images: + - /path/to/picture.jpg +``` From f0b0e8b8058fdc8c8064a81a651dec5699943e44 Mon Sep 17 00:00:00 2001 From: Dan Klaffenbach Date: Fri, 19 Mar 2021 22:09:41 +0100 Subject: [PATCH 40/90] Add join/unjoin documentation for media_player (#16442) --- source/_integrations/media_player.markdown | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/source/_integrations/media_player.markdown b/source/_integrations/media_player.markdown index 78d48f85693..60430774f15 100644 --- a/source/_integrations/media_player.markdown +++ b/source/_integrations/media_player.markdown @@ -14,7 +14,7 @@ Interacts with media players on your network. ## Services ### Media control services -Available services: `turn_on`, `turn_off`, `toggle`, `volume_up`, `volume_down`, `volume_set`, `volume_mute`, `media_play_pause`, `media_play`, `media_pause`, `media_stop`, `media_next_track`, `media_previous_track`, `clear_playlist`, `shuffle_set`, `repeat_set`, `play_media`, `select_source`, `select_sound_mode` +Available services: `turn_on`, `turn_off`, `toggle`, `volume_up`, `volume_down`, `volume_set`, `volume_mute`, `media_play_pause`, `media_play`, `media_pause`, `media_stop`, `media_next_track`, `media_previous_track`, `clear_playlist`, `shuffle_set`, `repeat_set`, `play_media`, `select_source`, `select_sound_mode`, `join`, `unjoin` | Service data attribute | Optional | Description | | ---------------------- | -------- | ------------------------------------------------ | @@ -156,6 +156,21 @@ Currently only supported on [Sonos](/integrations/sonos), [Spotify](/integration | `entity_id` | yes | Target a specific media player. For example `media_player.kitchen`| | `repeat` | no | `off`/`all`/`one` for setting repeat mode | +#### Service `media_player.join` + +Allows to group media players together for synchronous playback. Only works on supported multiroom audio systems. + +| Service data attribute | Optional | Description | +| ---------------------- | -------- | ---------------------------------------------------- | +| `entity_id` | yes | The media player entity whose playback will be expanded to the players specified in `group_members`. | +| `group_members` | no | The player entities which will be synced with the playback from `entity_id`. | + +#### Service `media_player.unjoin` + +| Service data attribute | Optional | Description | +| ---------------------- | -------- | ---------------------------------------------------- | +| `entity_id` | yes | Unjoin this media player from any player groups. | + ### Device Class The way media players are displayed in the frontend can be modified in the [customize section](/getting-started/customizing-devices/). The following device classes are supported for media players: From 324ce5c8deb0ddbabfbb93722d7450c00d754c3a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 21 Mar 2021 21:17:54 -1000 Subject: [PATCH 41/90] Update august to be cloud push (#17074) --- source/_integrations/august.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_integrations/august.markdown b/source/_integrations/august.markdown index c357686cd2f..2d82264b568 100644 --- a/source/_integrations/august.markdown +++ b/source/_integrations/august.markdown @@ -8,7 +8,7 @@ ha_category: - Camera - Lock ha_release: 0.64 -ha_iot_class: Cloud Polling +ha_iot_class: Cloud Push ha_config_flow: true ha_codeowners: - '@bdraco' From dc1b6f8786a26961255a3d63c29013994b762ef1 Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Mon, 22 Mar 2021 07:59:33 -0700 Subject: [PATCH 42/90] Add documentation for Hyperion effect hide option (#16344) --- source/_integrations/hyperion.markdown | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/_integrations/hyperion.markdown b/source/_integrations/hyperion.markdown index d7c6ae197f0..f2e0b0ebbd7 100644 --- a/source/_integrations/hyperion.markdown +++ b/source/_integrations/hyperion.markdown @@ -32,8 +32,9 @@ All configuration options are offered from the frontend. Choose `Options` under relevant entry on the `Integrations` page. Options supported: -- **priority**: The priority for color and effects, make sure this is lower then the streaming sources priority in hyperion itself (typically lower than 200 is appropriate). - +- **Priority**: The priority for color and effects, make sure this is lower then the streaming sources priority in hyperion itself (typically lower than 200 is appropriate). +- **Effects to hide**: An optional selection of effects to hide from the light effects + list. New effects added to the Hyperion server will be shown by default. ## Hyperion Instances This integration supports multiple Hyperion instances running on a single Hyperion From ed89896ab3f3bac673c689077671541a7ce0e8b9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 22 Mar 2021 05:39:45 -1000 Subject: [PATCH 43/90] Update homekit for activity based remotes (#17081) --- source/_integrations/homekit.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_integrations/homekit.markdown b/source/_integrations/homekit.markdown index cba7290dd81..947a7f8e572 100644 --- a/source/_integrations/homekit.markdown +++ b/source/_integrations/homekit.markdown @@ -307,7 +307,7 @@ It is recommended to only edit a HomeKit instance in the UI that was created in ### Accessory mode -When exposing a Camera or Television media player (a `media_player` with device class `tv`) to HomeKit, `mode` must be set to `accessory`, and the include filter should be setup to only include a single entity. +When exposing a Camera, Activity based remote (a `remote` that supports activities), or Television media player (a `media_player` with device class `tv`) to HomeKit, `mode` must be set to `accessory`, and the include filter should be setup to only include a single entity. To quickly add all accessory modes entities in the UI: From 28a4c4a642f3071bc560e308b027928d09df7fea Mon Sep 17 00:00:00 2001 From: Kevin Worrel <37058192+dieselrabbit@users.noreply.github.com> Date: Mon, 22 Mar 2021 08:41:31 -0700 Subject: [PATCH 44/90] Update screenlogic from water_heater to climate (#17073) Update screenlogic for move from water_heater to climate --- source/_integrations/screenlogic.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/_integrations/screenlogic.markdown b/source/_integrations/screenlogic.markdown index be182dacf94..866349f6c7a 100644 --- a/source/_integrations/screenlogic.markdown +++ b/source/_integrations/screenlogic.markdown @@ -4,10 +4,10 @@ description: "Instructions on how to integrate a ScreenLogic gateway within Home ha_release: "2021.4" ha_category: - Hub - - Sensor - Binary Sensor + - Climate + - Sensor - Switch - - Water Heater ha_iot_class: "Local Polling" ha_quality_scale: gold ha_config_flow: true @@ -16,10 +16,10 @@ ha_codeowners: - '@dieselrabbit' ha_domain: screenlogic ha_platforms: - - switch - binary_sensor + - climate - sensor - - water_heater + - switch --- The Pentair ScreenLogic integration allows you to integrate your Pentair Intellitouch or EasyTouch pool controller with Home Assistant via the [Pentair ScreenLogic](https://www.pentair.com/en-us/products/residential/pool-spa-equipment/pool-automation/screenlogic2_interfaceforintellitouchandeasytouchautomationsystems.html) gateway. From 9582b227bc2d42aa1468690ba272a394536cb593 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 24 Mar 2021 15:05:07 -1000 Subject: [PATCH 45/90] Update zeroconf default behavior for most common setups (including Home Assistant Operating System) (#17124) --- source/_integrations/zeroconf.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/_integrations/zeroconf.markdown b/source/_integrations/zeroconf.markdown index 55f500cf875..a578cd77ac1 100644 --- a/source/_integrations/zeroconf.markdown +++ b/source/_integrations/zeroconf.markdown @@ -30,10 +30,10 @@ zeroconf: type: map keys: default_interface: - description: By default, `zeroconf` will attempt to bind to all interfaces. For systems running using network isolation or similar, this may result in `zeroconf` being unavailable. Change this option to `true` if `zeroconf` does not function. + description: By default, `zeroconf` will broadcast on the default interface. For systems that require broadcasting `mdns` on all interfaces, change this option to `false` if `zeroconf` does not function. required: false type: boolean - default: false + default: true ipv6: description: By default, `zeroconf` will enable IPv6 support. If your network has trouble with IPv6 being enabled, you can set this option to `false`. required: false From 6db4074bce5e1b73df1b4559fc24e37959031d2a Mon Sep 17 00:00:00 2001 From: Boris Gulay Date: Thu, 25 Mar 2021 11:18:35 +0300 Subject: [PATCH 46/90] Add new protocol key descr for graphite (#15780) Co-authored-by: Klaas Schoute Co-authored-by: Franck Nijhof --- source/_integrations/graphite.markdown | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/_integrations/graphite.markdown b/source/_integrations/graphite.markdown index 32b19ee2862..03b766a0650 100644 --- a/source/_integrations/graphite.markdown +++ b/source/_integrations/graphite.markdown @@ -29,6 +29,11 @@ port: required: false type: integer default: 2003 +protocol: + description: "Type of communication protocol: `tcp` or `udp`." + required: false + type: string + default: tcp prefix: description: Prefix is the metric prefix in graphite. required: false From 6daf63dbddb1c71ae03b7e36123a0ed7e3e1466e Mon Sep 17 00:00:00 2001 From: Alexey Kustov Date: Thu, 25 Mar 2021 22:38:25 +0400 Subject: [PATCH 47/90] Add opportunity to define token for each message (#16771) --- source/_integrations/notify_events.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/source/_integrations/notify_events.markdown b/source/_integrations/notify_events.markdown index dfac00790a3..ca1b1e39eb5 100644 --- a/source/_integrations/notify_events.markdown +++ b/source/_integrations/notify_events.markdown @@ -104,6 +104,7 @@ The following attributes can be placed inside `data` for extended functionality. | `priority` | For recipients which supports priority, the message will be highlighted accordingly.
    Available values: `lowest`, `low`, `normal`, `high`, `highest`. | `images` | Array of images to attach (see item properties below). | `files` | Array of files to attach (see item properties below). +| `token` | Notify.Events channel token (in case you want to override the channel to get this message to). Every item of images and files has the following properties: From 1deeb0433dd4ad186e2903e4f460214d4b2430c6 Mon Sep 17 00:00:00 2001 From: Christian Soltenborn Date: Mon, 29 Mar 2021 09:41:52 +0200 Subject: [PATCH 48/90] Added docs for new attributes (#16948) --- source/_integrations/weather.template.markdown | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/_integrations/weather.template.markdown b/source/_integrations/weather.template.markdown index c148a45226c..50235f8b044 100644 --- a/source/_integrations/weather.template.markdown +++ b/source/_integrations/weather.template.markdown @@ -56,6 +56,10 @@ humidity_template: description: The current humidity. required: true type: template +attribution_template: + description: The attribution to be shown in the frontend. + required: false + type: string pressure_template: description: The current air pressure. required: false @@ -64,6 +68,18 @@ wind_speed_template: description: The current wind speed. required: false type: template +wind_bearing_template: + description: The current wind bearing. + required: false + type: template +ozone_template: + description: The current ozone level. + required: false + type: template +visibility_template: + description: The current visibility. + required: false + type: template forecast_template: description: Daily forecast data. required: false From 18615a11b9a9552856f2613d8c8c0e4d3d001ef6 Mon Sep 17 00:00:00 2001 From: jan iversen Date: Mon, 29 Mar 2021 09:42:18 +0200 Subject: [PATCH 49/90] Update modbus configuration to use new (#16678) Co-authored-by: Franck Nijhof --- .../binary_sensor.modbus.markdown | 87 --- source/_integrations/climate.modbus.markdown | 125 --- source/_integrations/cover.modbus.markdown | 210 ----- source/_integrations/modbus.markdown | 724 ++++++++++++++++-- source/_integrations/sensor.modbus.markdown | 145 ---- source/_integrations/switch.modbus.markdown | 137 ---- source/_redirects | 7 +- 7 files changed, 674 insertions(+), 761 deletions(-) delete mode 100644 source/_integrations/binary_sensor.modbus.markdown delete mode 100644 source/_integrations/climate.modbus.markdown delete mode 100644 source/_integrations/cover.modbus.markdown delete mode 100644 source/_integrations/sensor.modbus.markdown delete mode 100644 source/_integrations/switch.modbus.markdown diff --git a/source/_integrations/binary_sensor.modbus.markdown b/source/_integrations/binary_sensor.modbus.markdown deleted file mode 100644 index 33424ab389a..00000000000 --- a/source/_integrations/binary_sensor.modbus.markdown +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "Modbus Binary Sensor" -description: "Instructions on how to set up Modbus binary sensors within Home Assistant." -ha_category: - - Binary Sensor -ha_release: 0.28 -ha_iot_class: Local Push -ha_domain: modbus ---- - -The `modbus` binary sensor allows you to gather data from [Modbus](http://www.modbus.org/) coils. - -## Configuration - -To use your Modbus binary sensors in your installation, add the following to your `configuration.yaml` file: - -```yaml -# Example configuration.yaml entry -binary_sensor: - - platform: modbus - inputs: - - name: Sensor1 - hub: hub1 - slave: 1 - address: 100 - - name: Sensor2 - hub: hub1 - slave: 1 - address: 110 - input_type: discrete_input -``` - -{% configuration %} -inputs: - description: The array contains a list of coils and discrete inputs to read from. - required: true - type: [map, list] - keys: - name: - description: Name of the sensor. - required: true - type: string - hub: - description: The name of the hub. - required: false - default: modbus_hub - type: string - slave: - description: The number of the slave (Optional for TCP and UDP Modbus). - required: true - type: integer - address: - description: Coil or discrete input Modbus address. - required: true - type: integer - input_type: - description: Modbus input type (coil, discrete_input), default coil. - required: false - type: string - device_class: - description: The [type/class](/integrations/binary_sensor/#device-class) of the binary sensor to set the icon in the frontend. - required: false - type: device_class - default: None -{% endconfiguration %} - -It's possible to change the default 30 seconds scan interval for the sensor updates as shown in the [Platform options](/docs/configuration/platform_options/#scan-interval) documentation. - -## Full example - -Example a sensor with a 10 seconds scan interval: - -```yaml -binary_sensor: - - platform: modbus - scan_interval: 10 - inputs: - - name: Sensor1 - hub: hub1 - slave: 1 - address: 100 - - name: Sensor2 - hub: hub1 - slave: 1 - address: 110 - input_type: discrete_input -``` diff --git a/source/_integrations/climate.modbus.markdown b/source/_integrations/climate.modbus.markdown deleted file mode 100644 index 1deeeab1c4b..00000000000 --- a/source/_integrations/climate.modbus.markdown +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: "Modbus Climate" -description: "Instructions how to integrate a Modbus thermostat within Home Assistant." -ha_category: - - Climate -ha_release: 0.68 -ha_iot_class: Local Polling -ha_domain: modbus ---- - - -The `modbus` thermostat allows you to use a sensor value (current temperature) and target value (target temperature) from [Modbus](http://www.modbus.org/) registers. - -## Configuration - -To use your Modbus thermostat in your installation, add the following to your `configuration.yaml` file: - -```yaml -# Example configuration.yaml entry -modbus: - - name: hub1 - type: tcp - host: IP_ADDRESS - port: 502 - - climates: - - name: Watlow F4T - slave: 1 - data_type: uint - data_count: 1 - scale: 0.1 - offset: 0 - precision: 1 - max_temp: 30 - min_temp: 15 - temp_step: 1 - target_temp_register: 2782 - current_temp_register: 27586 -``` - -{% configuration %} -name: - description: Name of the device - required: true - type: string -slave: - description: The number of the slave (Optional for tcp and upd Modbus, use 1). - required: true - type: integer -target_temp_register: - description: Register number for target temperature (Setpoint). - required: true - type: integer -current_temp_register: - description: Register number for current temperature (Process value). - required: true - type: integer -current_temp_register_type: - description: Modbus register type (holding, input) for current temperature, default holding. - required: false - type: string - default: holding -data_type: - description: Response representation (int, uint, float, custom). If float selected, value will converted to IEEE 754 floating point format. - required: false - type: string - default: float -structure: - description: "If `data_type` is custom specified a double-quoted Python struct is expected here, to format the string to unpack the value. See Python documentation for details. Example: `>i`." - required: false - type: string - default: ">f" -data_count: - description: Number of registers to read. - required: false - type: integer - default: 2 -precision: - description: Number of valid decimals. - required: false - type: integer - default: 1 -scale: - description: Scale factor (output = scale * value + offset). - required: false - type: float - default: 1 -offset: - description: Final offset (output = scale * value + offset). - required: false - type: float - default: 0 -max_temp: - description: Maximum setpoint temperature. - required: false - type: integer - default: 35 -min_temp: - description: Maximum setpoint temperature. - required: false - type: integer - default: 5 -temp_step: - description: The supported step size a target temperature can be increased/decreased. - required: false - type: float - default: 0.5 -temperature_unit: - description: Temperature unit reported by the current_temp_register. C or F - required: false - type: string - default: C -scan_interval: - description: Defines the update interval of the sensor in seconds. - required: false - type: integer - default: 15 -{% endconfiguration %} - - -### Services - -| Service | Description | -| ------- | ----------- | -| set_temperature | Set Temperature. Requires `value` to be passed in, which is the desired target temperature. `value` should be in the same type as `data_type` | diff --git a/source/_integrations/cover.modbus.markdown b/source/_integrations/cover.modbus.markdown deleted file mode 100644 index 59f6d3f25a6..00000000000 --- a/source/_integrations/cover.modbus.markdown +++ /dev/null @@ -1,210 +0,0 @@ ---- -title: "Modbus Cover" -description: "Instructions on how to integrate Modbus covers into Home Assistant." -ha_category: - - Cover -ha_release: 0.116 -ha_iot_class: Local Polling -ha_domain: modbus ---- - -The `modbus` cover platform allows you to control [Modbus](http://www.modbus.org/) covers (such as blinds, a roller shutter, or a garage door). - -## Configuration - -At the moment, we support the opening and closing of a cover. You can control your covers either using coils or holding registers. - -Cover that uses the `coil` attribute is not able to determine intermediary states such as opening and closing. Coil stores only two states — "0" means cover closed, and "1" implies cover open. To allow detecting intermediary states, we added an optional `status_register` attribute. It will enable you to write your command (e.g., to open a cover) into a coil, and read current cover status back through the register. Additionally, you can specify values for `state_open`, `state_opening`, `state_closed`, and `state_closing` attributes. These will be matched with the value read from the `status_register`. - -If your cover uses holding register to send commands (defined by the `register` attribute), it can also read the intermediary states. To adjust which value represents what state, you can fine-tune the optional state attributes, like `state_open`. These optional state values are also used for specifying values written into the register. If you specify an optional status_register attribute, cover states will be read from status_register instead of the register used for sending commands. - -To use Modbus covers in your installation, add the following to your `configuration.yaml` file: - -```yaml -# Example configuration.yaml entry -modbus: - - name: hub1 - type: tcp - host: IP_ADDRESS - port: 502 - - covers: - - name: Door1 - device_class: door - scan_interval: 1 - coil: 0 - - name: Door2 - device_class: door - scan_interval: 1 - coil: 1 - status_register: 1 - - name: Door3 - slave: 2 - device_class: door - scan_interval: 1 - register: 0 - state_open: 1 - state_closed: 0 -``` - -{% configuration %} -covers: - description: The array contains a list of all your Modbus covers. - required: true - type: map - keys: - slave: - description: The number of the slave (can be omitted for tcp and udp Modbus). - required: false - default: 1 - type: integer - name: - description: Name of the switch. - required: true - type: string - coil: - description: Coil address; can be omitted if a register attribute is specified. Coil and register attributes are mutually exclusive, and you need to always specify one of them. - required: true - type: integer - register: - description: Holding register address; can be omitted if a coil attribute is specified. Coil and register attributes are mutually exclusive, and you need to always specify one of them. - required: true - type: integer - status_register: - description: An address of an register, from which all the cover states will be read. If you specified `register` attribute, and not `status_register` attribute, your main register will also be used as a status register. - required: false - type: integer - status_register_type: - description: Modbus register type (holding, input), default holding. - required: false - type: string - state_open: - description: A value in `status_register` or `register` representing an open cover. If your configuration uses an `register` attribute, this value will be also written into a holding register to open the cover. - required: false - default: 1 - type: integer - state_closed: - description: A value in `status_register` or `register` representing a closed cover. If your configuration uses an `register` attribute, this value will be also written into a holding register to close the cover. - required: false - default: 0 - type: integer - state_opening: - description: A value in `status_register` or `register` telling us that the cover is opening at the moment. Note that this state should be also supported on your connected Modbus cover. If it won't write this intermediary state into the register, this state won't be detected. - required: false - default: 2 - type: integer - state_closing: - description: A value in `status_register` or `register` telling us that the cover is closing at the moment. Note that this state should be also supported on your connected Modbus cover. If it won't write this intermediary state into the register, this state won't be detected. - required: false - default: 2 - type: integer - device_class: - description: The [type/class](/integrations/cover/#device-class) of the cover to set the icon in the frontend. - required: false - type: device_class - default: None - scan_interval: - description: Defines the update interval of the sensor in seconds. - required: false - type: integer - default: 15 -{% endconfiguration %} - -## Examples - -In this section, you find some real-life examples of how to use this light. - -### Modbus cover controlled by a coil - -This example shows a configuration for a Modbus cover controlled using a coil. Intermediary states like opening/closing are not supported. The cover state is polled from Modbus every 10 seconds. - -```yaml -modbus: - - name: hub1 - type: tcp - host: IP_ADDRESS - port: 502 - - covers: - - name: Door1 - slave: 1 - coil: 1 - device_class: door - scan_interval: 10 - - name: Door2 - slave: 2 - coil: 2 - device_class: door - scan_interval: 10 -``` - -### Modbus cover controlled by a coil, it's state is read from the register - -This example shows a configuration for a Modbus cover controlled using a coil. Actual cover state is read from the `status_register`. We've also specified register values to match with the states open/opening/closed/closing. The cover state is polled from Modbus every 10 seconds. - -```yaml -modbus: - - name: hub1 - type: tcp - host: IP_ADDRESS - port: 502 - - covers: - - name: Door1 - slave: 1 - device_class: door - scan_interval: 10 - coil: 1 - status_register: 1 - status_register_type: input - state_opening: 1 - state_open: 2 - state_closing: 3 - state_closed: 4 -``` - -### Modbus cover controlled by a holding register - -This example shows a configuration for a Modbus cover controlled using a holding register, from which we also read current cover state. We've also specified register values to match with the states open/opening/closed/closing. The cover state is polled from Modbus every 10 seconds. - -```yaml -modbus: - - name: hub1 - type: tcp - host: IP_ADDRESS - port: 502 - - covers: - - name: Door1 - slave: 1 - device_class: door - scan_interval: 10 - register: 1 - state_opening: 1 - state_open: 2 - state_closing: 3 - state_closed: 4 -``` - -### Modbus cover controlled by a holding register, it's state is read from the status register - -This example shows a configuration for a Modbus cover controlled using a holding register. However, cover state is read from a `status_register`. In this case, we've specified only values for `state_open` and `state_closed`, for the rest, default values are used. The cover state is polled from Modbus every 10 seconds. - -```yaml -modbus: - - name: hub1 - type: tcp - host: IP_ADDRESS - port: 502 - - covers: - - name: Door1 - slave: 1 - device_class: door - scan_interval: 10 - register: 1 - status_register: 2 - register_type: holding - state_open: 1 - state_closed: 0 -``` diff --git a/source/_integrations/modbus.markdown b/source/_integrations/modbus.markdown index 1da25a6d5bb..5d9e7f06b9e 100644 --- a/source/_integrations/modbus.markdown +++ b/source/_integrations/modbus.markdown @@ -1,6 +1,6 @@ --- title: Modbus -description: Instructions on how to integrate Modbus within Home Assistant. +description: Instructions on how to integrate Modbus and platforms. ha_category: - Hub ha_release: pre 0.7 @@ -23,7 +23,16 @@ It supports various types of devices which can be controlled over serial, TCP, a ## Configuration -The configuration for adding modbus to your installation depends on the connection type, either a network or serial connection. +How to add modbus to your installation depends on the connection type, either a network or serial connection. + +Platforms: + - binary_sensor + - climate + - cover + - sensor + - switch + +are all defined as part of the modbus configuration. The old configuration style, (having each outside the modbus configuration is still supported, but will cause a warning, and will be removed in a later release). ### Network connection @@ -32,40 +41,40 @@ For a network connection, add the following to your `configuration.yaml` file: ```yaml # Example configuration.yaml entry for a TCP connection modbus: - name: hub1 - type: tcp - host: IP_ADDRESS - port: 2020 + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 ``` {% configuration %} -type: - description: Type of the connection to Modbus. Possible values are `tcp` (Modbus TCP protocol according to "MODBUS Messaging Implementation Guide version 1.0b" provided by Schneider Automation.), `udp`(Modbus TCP form, but using UDP for transport. It removes the overheads required for TCP.) and `rtuovertcp` (Modbus RTU message transmitted with a TCP/IP wrapper and sent over a network instead of serial lines.). - required: true - type: string -host: - description: The IP address of your Modbus device, e.g., 192.168.1.1. - required: true - type: string -port: - description: The network port for the communication. - required: true - type: integer -name: - description: Name for this hub. Must be unique, so it is required when setting up multiple instances. - required: false - default: modbus_hub - type: string -timeout: - description: Timeout for slave response in seconds. - required: false - default: 3 - type: integer delay: description: Time to sleep in seconds after connecting and before sending messages. Some modbus-tcp servers need a short delay typically 1-2 seconds in order to prepare the communication. If a server accepts connecting, but there is no response to the requests send, this parameter might help. required: false default: 0 type: integer +host: + description: The IP address of your Modbus device, e.g., 192.168.1.1. + required: true + type: string +name: + description: Name for this hub. Must be unique, so it is required when setting up multiple instances. + required: false + default: modbus_hub + type: string +port: + description: The network port for the communication. + required: true + type: integer +timeout: + description: Timeout for slave response in seconds. + required: false + default: 3 + type: integer +type: + description: Type of the connection to Modbus. Possible values are `tcp` (Modbus TCP protocol according to "MODBUS Messaging Implementation Guide version 1.0b" provided by Schneider Automation.), `udp`(Modbus TCP form, but using UDP for transport. It removes the overheads required for TCP.) and `rtuovertcp` (Modbus RTU message transmitted with a TCP/IP wrapper and sent over a network instead of serial lines.). + required: true + type: string {% endconfiguration %} ### Serial connection @@ -75,58 +84,661 @@ For a serial connection, add the following to your `configuration.yaml` file: ```yaml # Example configuration.yaml entry for a serial connection modbus: - name: hub1 - type: serial - method: rtu - port: /dev/ttyUSB0 - baudrate: 9600 - stopbits: 1 - bytesize: 8 - parity: N + - name: hub1 + type: serial + method: rtu + port: /dev/ttyUSB0 + baudrate: 9600 + stopbits: 1 + bytesize: 8 + parity: N ``` {% configuration %} -type: - description: "Type of the connection to Modbus, needs to be `serial` for this setup." - required: true - type: string -method: - description: "Method of the connection to Modbus, either `rtu` or `ascii`." - required: true - type: string -port: - description: The port where your Modbus device is connected to your Home Assistant host. - required: true - type: string baudrate: description: The speed for the serial connection. required: true type: integer -stopbits: - description: "The stopbits for the serial connection, either `1` or `2`." - required: true - type: integer bytesize: description: "The bytesize for the serial connection; can be `5`, `6`, `7` or `8`." required: true type: integer -parity: - description: "The parity for the serial connection; can be `E`, `O` or `N`." +delay: + description: Time to sleep in seconds after connecting and before sending messages. Some modbus servers need a short delay typically 1-2 seconds in order to prepare the communication. If a server accepts connecting, but there is no response to the requests send, this parameter might help. + required: false + default: 0 + type: integer +method: + description: "Method of the connection to Modbus, either `rtu` or `ascii`." required: true type: string name: description: Name for this hub. Must be unique, so it is required when setting up multiple instances. required: false - default: default + default: modbus_hub type: string +parity: + description: "The parity for the serial connection; can be `E`, `O` or `N`." + required: true + type: string +port: + description: The port where your Modbus device is connected to your Home Assistant host. + required: true + type: string +stopbits: + description: "The stopbits for the serial connection, either `1` or `2`." + required: true + type: integer timeout: description: Timeout for slave response in seconds. required: false default: 3 type: integer +type: + description: "Type of the connection to Modbus, needs to be `serial` for this setup." + required: true + type: string {% endconfiguration %} -### Multiple connections +### Configuring platform binary sensor + +The `modbus` binary sensor allows you to gather data from [Modbus](http://www.modbus.org/) coils with state ON/OFF. + +To use your Modbus binary sensors in your installation, add the following to your `configuration.yaml` file: +```yaml +# Example configuration.yaml entry for binary_sensor configuration +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + binary_sensors: + - name: Sensor1 + slave: 1 + address: 100 + - name: Sensor2 + address: 110 + input_type: discrete_input +``` +{% configuration %} +binary_sensors: + description: A list of all binary_sensors available in this modbus instance. + required: false + type: [map] + keys: + device_class: + description: Device class to be used for the UI (e.g. "door"). + required: false + type: string + input_type: + description: type of adddress (holding/discrete/coil) + required: false + default: holding + type: integer + name: + description: Name for this binary_sensor. Must be unique. + required: true + type: string + scan_interval: + description: Defines the update interval of the sensor in seconds. + required: false + type: integer + default: 15 + slave: + description: The number of the slave. + required: false + type: integer +{% endconfiguration %} + + +### Configuring platform climate + +To use your Modbus thermostat in your installation, add the following to your `configuration.yaml` file: + +```yaml +# Example configuration.yaml entry +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + climates: + - name: Watlow F4T + slave: 1 + data_type: uint + data_count: 1 + scale: 0.1 + offset: 0 + precision: 1 + max_temp: 30 + min_temp: 15 + temp_step: 1 + target_temp_register: 2782 + current_temp_register: 27586 +``` + +{% configuration %} +climates: + description: A list of all climates available in this modbus instance. + required: false + type: [map] + keys: + current_temp_register: + description: Register number for current temperature (Process value). + required: true + type: integer + current_temp_register_type: + description: Modbus register type (holding, input) for current temperature, default holding. + required: false + type: string + default: holding + data_count: + description: Number of registers to read. + required: false + type: integer + default: 2 + data_type: + description: Response representation (int, uint, float, custom). If float selected, value will converted to IEEE 754 floating point format. + required: false + type: string + default: float + min_temp: + description: Maximum setpoint temperature. + required: false + type: integer + default: 5 + name: + description: Name of the device + required: true + type: string + offset: + description: Final offset (output = scale * value + offset). + required: false + type: float + default: 0 + precision: + description: Number of valid decimals. + required: false + type: integer + default: 1 + scale: + description: Scale factor (output = scale * value + offset). + required: false + type: float + default: 1 + scan_interval: + description: Defines the update interval of the sensor in seconds. + required: false + type: integer + default: 15 + slave: + description: The number of the slave (Optional for tcp and upd Modbus, use 1). + required: true + type: integer + structure: + description: "If `data_type` is custom specified a double-quoted Python struct is expected here, to format the string to unpack the value. See Python documentation for details. Example: `>i`." + required: false + type: string + default: ">f" + target_temp_register: + description: Register number for target temperature (Setpoint). + required: true + type: integer + temp_step: + description: The supported step size a target temperature can be increased/decreased. + required: false + type: float + default: 0.5 + temperature_unit: + description: Temperature unit reported by the current_temp_register. C or F + required: false + type: string + default: C +{% endconfiguration %} + +#### Services + +| Service | Description | +| ------- | ----------- | +| set_temperature | Set Temperature. Requires `value` to be passed in, which is the desired target temperature. `value` should be in the same type as `data_type` | + +### Configuring platform cover + +The `modbus` cover platform allows you to control [Modbus](http://www.modbus.org/) covers (such as blinds, a roller shutter, or a garage door). + +At the moment, we support the opening and closing of a cover. You can control your covers either using coils or holding registers. + +Cover that uses the `coil` attribute is not able to determine intermediary states such as opening and closing. Coil stores only two states — "0" means cover closed, and "1" implies cover open. To allow detecting intermediary states, we added an optional `status_register` attribute. It will enable you to write your command (e.g., to open a cover) into a coil, and read current cover status back through the register. Additionally, you can specify values for `state_open`, `state_opening`, `state_closed`, and `state_closing` attributes. These will be matched with the value read from the `status_register`. + +If your cover uses holding register to send commands (defined by the `register` attribute), it can also read the intermediary states. To adjust which value represents what state, you can fine-tune the optional state attributes, like `state_open`. These optional state values are also used for specifying values written into the register. If you specify an optional status_register attribute, cover states will be read from status_register instead of the register used for sending commands. + +To use Modbus covers in your installation, add the following to your `configuration.yaml` file: + +```yaml +# Example configuration.yaml entry +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + covers: + - name: Door1 + device_class: door + scan_interval: 1 + coil: 0 + - name: Door2 + device_class: door + scan_interval: 1 + coil: 1 + status_register: 1 + - name: Door3 + slave: 2 + device_class: door + scan_interval: 1 + register: 0 + state_open: 1 + state_closed: 0 +``` + +{% configuration %} +covers: + description: The array contains a list of all your Modbus covers. + required: true + type: map + keys: + coil: + description: Coil address; can be omitted if a register attribute is specified. Coil and register attributes are mutually exclusive, and you need to always specify one of them. + required: true + type: integer + device_class: + description: The [type/class](/integrations/cover/#device-class) of the cover to set the icon in the frontend. + required: false + type: device_class + default: None + name: + description: Name of the switch. + required: true + type: string + register: + description: Holding register address; can be omitted if a coil attribute is specified. Coil and register attributes are mutually exclusive, and you need to always specify one of them. + required: true + type: integer + scan_interval: + description: Defines the update interval of the sensor in seconds. + required: false + type: integer + default: 15 + slave: + description: The number of the slave (can be omitted for tcp and udp Modbus). + required: false + default: 1 + type: integer + state_open: + description: A value in `status_register` or `register` representing an open cover. If your configuration uses an `register` attribute, this value will be also written into a holding register to open the cover. + required: false + default: 1 + type: integer + state_closed: + description: A value in `status_register` or `register` representing a closed cover. If your configuration uses an `register` attribute, this value will be also written into a holding register to close the cover. + required: false + default: 0 + type: integer + state_opening: + description: A value in `status_register` or `register` telling us that the cover is opening at the moment. Note that this state should be also supported on your connected Modbus cover. If it won't write this intermediary state into the register, this state won't be detected. + required: false + default: 2 + type: integer + state_closing: + description: A value in `status_register` or `register` telling us that the cover is closing at the moment. Note that this state should be also supported on your connected Modbus cover. If it won't write this intermediary state into the register, this state won't be detected. + required: false + default: 2 + type: integer + status_register: + description: An address of an register, from which all the cover states will be read. If you specified `register` attribute, and not `status_register` attribute, your main register will also be used as a status register. + required: false + type: integer + status_register_type: + description: Modbus register type (holding, input), default holding. + required: false + type: string +{% endconfiguration %} + +#### Example: Modbus cover controlled by a coil + +This example shows a configuration for a Modbus cover controlled using a coil. Intermediary states like opening/closing are not supported. The cover state is polled from Modbus every 10 seconds. + +```yaml +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + covers: + - name: Door1 + slave: 1 + coil: 1 + device_class: door + scan_interval: 10 + - name: Door2 + slave: 2 + coil: 2 + device_class: door + scan_interval: 10 +``` + +#### Example: Modbus cover controlled by a coil, it's state is read from the register + +This example shows a configuration for a Modbus cover controlled using a coil. Actual cover state is read from the `status_register`. We've also specified register values to match with the states open/opening/closed/closing. The cover state is polled from Modbus every 10 seconds. + +```yaml +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + covers: + - name: Door1 + slave: 1 + device_class: door + scan_interval: 10 + coil: 1 + status_register: 1 + status_register_type: input + state_opening: 1 + state_open: 2 + state_closing: 3 + state_closed: 4 +``` + +#### Example: Modbus cover controlled by a holding register + +This example shows a configuration for a Modbus cover controlled using a holding register, from which we also read current cover state. We've also specified register values to match with the states open/opening/closed/closing. The cover state is polled from Modbus every 10 seconds. + +```yaml +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + covers: + - name: Door1 + slave: 1 + device_class: door + scan_interval: 10 + register: 1 + state_opening: 1 + state_open: 2 + state_closing: 3 + state_closed: 4 +``` + +#### Example: Modbus cover controlled by a holding register, it's state is read from the status register + +This example shows a configuration for a Modbus cover controlled using a holding register. However, cover state is read from a `status_register`. In this case, we've specified only values for `state_open` and `state_closed`, for the rest, default values are used. The cover state is polled from Modbus every 10 seconds. + +```yaml +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + + covers: + - name: Door1 + slave: 1 + device_class: door + scan_interval: 10 + register: 1 + status_register: 2 + register_type: holding + state_open: 1 + state_closed: 0 +``` + +### Configuring platform sensor + +The `modbus` cover platform allows you to control [Modbus](http://www.modbus.org/) covers (such as blinds, a roller shutter, or a garage door). + + +The `modbus` sensor allows you to gather data from [Modbus](http://www.modbus.org/) registers. + +To use your Modbus sensors in your installation, add the following to your `configuration.yaml` file: + +```yaml +# Example configuration.yaml entry +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + sensors: + - name: Sensor1 + unit_of_measurement: °C + slave: 1 + address: 100 + - name: Sensor2 + unit_of_measurement: mg + slave: 1 + register: 110 + count: 2 + - name: Sensor3 + unit_of_measurement: °C + slave: 1 + address: 120 + input_type: input + data_type: float + scale: 0.01 + offset: -273.16 + precision: 2 +``` + +{% configuration %} +sensors: + description: The array contains a list of all your Modbus sensors. + required: true + type: map + keys: + address: + description: Register number. + required: true + type: integer + count: + description: Number of registers to read. + required: false + type: integer + default: 1 + data_type: + description: Response representation (int, uint, float, string, custom). If float selected, value will be converted to IEEE 754 floating point format. + required: false + default: int + type: string + device_class: + description: The [type/class](/integrations/sensor/#device-class) of the sensor to set the icon in the frontend. + required: false + type: device_class + default: None + input_type: + description: Modbus register type (holding, input), default holding. + required: false + type: string + name: + description: Name of the sensor. + required: true + type: string + offset: + description: Final offset (output = scale * value + offset). + required: false + default: 0 + type: float + precision: + description: Number of valid decimals. + required: false + default: 0 + type: integer + reverse_order: + description: Reverse the order of registers when count >1. + required: false + default: false + type: boolean + scale: + description: Scale factor (output = scale * value + offset). + required: false + default: 1 + type: float + scan_interval: + description: Defines the update interval of the sensor in seconds. + required: false + type: integer + default: 15 + slave: + description: The number of the slave (Optional for tcp and upd Modbus). + required: true + type: integer + structure: + description: "If `data_type` is custom specified a double-quoted Python struct is expected here, to format the string to unpack the value. See Python documentation for details. Example: `>i`." + required: false + type: string + unit_of_measurement: + description: Unit to attach to value. + required: false + type: integer +{% endconfiguration %} + +
    + +If you specify scale or offset as floating point values, double precision floating point arithmetic will be used to calculate final value. This can cause loss of precision for values that are larger than 2^53. + +
    + +#### Full example + +Example a temperature sensor with a 10 seconds scan interval: + +```yaml +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + sensors: + - name: Room_1 + slave: 10 + address: 0 + input_type: holding + unit_of_measurement: °C + count: 1 + scale: 0.1 + offset: 0 + precision: 1 + data_type: integer +``` + +### Configuring platform switch + +The `modbus` switch platform allows you to control [Modbus](http://www.modbus.org/) coils or registers. + +To use your Modbus switches in your installation, add the following to your `configuration.yaml` file: + +```yaml +# Example configuration.yaml entry +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + switches: + - name: Switch1 + address: 13 + input_type: coil + - name: Switch2 + slave: 2 + address: 14 + input_type: coil + - name: Register1 + address: 11 + command_on: 1 + command_off: 0 +``` + +{% configuration %} +switches: + description: The array contains a list of all your Modbus switches. + required: true + type: map + keys: + address: + description: Coil number or register + required: true + type: integer + command_on: + description: Value to write to turn on the switch. + required: true + type: integer + command_off: + description: Value to write to turn off the switch. + required: true + type: integer + input_type: + description: type of adddress (holding/discrete/coil) + required: false + default: holding + type: integer + name: + description: Name of the switch. + required: true + type: string + scan_interval: + description: Defines the update interval of the sensor in seconds. + required: false + type: integer + default: 15 + slave: + description: The number of the slave (can be omitted for tcp and udp Modbus). + required: true + type: integer + state_on: + description: Register value when switch is on. + required: false + default: same as command_on + type: integer + state_off: + description: Register value when switch is off. + required: false + default: same as command_off + type: integer + verify_register: + description: Register to readback. + required: false + default: same as register + type: string + verify_state: + description: Define if is possible to readback the status of the switch. + required: false + default: true + type: boolean +{% endconfiguration %} + +#### Full example + +Example switches, for which the state is polled from Modbus every 10 seconds. + +```yaml +modbus: + - name: hub1 + type: tcp + host: IP_ADDRESS + port: 502 + switches: + - name: Switch1 + slave: 1 + address: 13 + input_type: coil + - name: Switch2 + slave: 2 + address: 14 +``` + +#### Multiple connections Multiple connections are possible, add something like the following to your `configuration.yaml` file: diff --git a/source/_integrations/sensor.modbus.markdown b/source/_integrations/sensor.modbus.markdown deleted file mode 100644 index 7c7d03a2cfb..00000000000 --- a/source/_integrations/sensor.modbus.markdown +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: Modbus Sensor -description: "Instructions on how to integrate Modbus sensors into Home Assistant." -ha_category: - - Sensor -ha_release: pre 0.7 -ha_iot_class: Local Push -ha_domain: modbus ---- - -The `modbus` sensor allows you to gather data from [Modbus](http://www.modbus.org/) registers. - -## Configuration - -To use your Modbus sensors in your installation, add the following to your `configuration.yaml` file: - -```yaml -# Example configuration.yaml entry -sensor: - platform: modbus - registers: - - name: Sensor1 - hub: hub1 - unit_of_measurement: °C - slave: 1 - register: 100 - - name: Sensor2 - hub: hub1 - unit_of_measurement: mg - slave: 1 - register: 110 - count: 2 - - name: Sensor3 - hub: hub1 - unit_of_measurement: °C - slave: 1 - register: 120 - register_type: input - data_type: float - scale: 0.01 - offset: -273.16 - precision: 2 -``` - -{% configuration %} -registers: - description: The array contains a list of relevant registers to read from. - required: true - type: map - keys: - name: - description: Name of the sensor. - required: true - type: string - hub: - description: The name of the hub. - required: false - default: modbus_hub - type: string - slave: - description: The number of the slave (Optional for tcp and upd Modbus). - required: true - type: integer - register: - description: Register number. - required: true - type: integer - register_type: - description: Modbus register type (holding, input), default holding. - required: false - type: string - unit_of_measurement: - description: Unit to attach to value. - required: false - type: integer - device_class: - description: The [type/class](/integrations/sensor/#device-class) of the sensor to set the icon in the frontend. - required: false - type: device_class - default: None - count: - description: Number of registers to read. - required: false - type: integer - default: 1 - reverse_order: - description: Reverse the order of registers when count >1. - required: false - default: false - type: boolean - scale: - description: Scale factor (output = scale * value + offset). - required: false - default: 1 - type: float - offset: - description: Final offset (output = scale * value + offset). - required: false - default: 0 - type: float - precision: - description: Number of valid decimals. - required: false - default: 0 - type: integer - data_type: - description: Response representation (int, uint, float, string, custom). If float selected, value will be converted to IEEE 754 floating point format. - required: false - default: int - type: string - structure: - description: "If `data_type` is custom specified a double-quoted Python struct is expected here, to format the string to unpack the value. See Python documentation for details. Example: `>i`." - required: false - type: string -{% endconfiguration %} - -It's possible to change the default 30 seconds scan interval for the sensor updates as shown in the [Platform options](/docs/configuration/platform_options/#scan-interval) documentation. - -
    - -If you specify scale or offset as floating point values, double precision floating point arithmetic will be used to calculate final value. This can cause loss of precision for values that are larger than 2^53. - -
    - -### Full example - -Example a temperature sensor with a 10 seconds scan interval: - -```yaml -sensor: -- platform: modbus - scan_interval: 10 - registers: - - name: Room_1 - hub: hub1 - slave: 10 - register: 0 - register_type: holding - unit_of_measurement: °C - count: 1 - scale: 0.1 - offset: 0 - precision: 1 - data_type: integer -``` diff --git a/source/_integrations/switch.modbus.markdown b/source/_integrations/switch.modbus.markdown deleted file mode 100644 index 0809e71a75c..00000000000 --- a/source/_integrations/switch.modbus.markdown +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: "Modbus Switch" -description: "Instructions on how to integrate Modbus switches into Home Assistant." -ha_category: - - Switch -ha_release: pre 0.7 -ha_iot_class: Local Push -ha_domain: modbus ---- - -The `modbus` switch platform allows you to control [Modbus](http://www.modbus.org/) coils or registers. - -## Configuration - -To use your Modbus switches in your installation, add the following to your `configuration.yaml` file: - -```yaml -# Example configuration.yaml entry -switch: - platform: modbus - coils: - - name: Switch1 - hub: hub1 - slave: 1 - coil: 13 - - name: Switch2 - slave: 2 - coil: 14 - registers: - - name: Register1 - hub: hub1 - slave: 1 - register: 11 - command_on: 1 - command_off: 0 -``` - -{% configuration %} -coils: - description: A list of relevant coils to read from/write to. - required: false - type: map - keys: - hub: - description: The name of the hub. - required: false - default: default - type: string - slave: - description: The number of the slave (can be omitted for tcp and udp Modbus). - required: true - type: integer - name: - description: Name of the switch. - required: true - type: string - coil: - description: Coil number. - required: true - type: integer -registers: - description: A list of relevant registers to read from/write to. - required: false - type: map - keys: - hub: - description: The hub to use. - required: false - default: default - type: string - slave: - description: The number of the slave (can be omitted for tcp and udp Modbus). - required: true - type: integer - name: - description: Name of the switch. - required: true - type: string - register: - description: Register number. - required: true - type: integer - command_on: - description: Value to write to turn on the switch. - required: true - type: integer - command_off: - description: Value to write to turn off the switch. - required: true - type: integer - verify_state: - description: Define if is possible to readback the status of the switch. - required: false - default: true - type: boolean - verify_register: - description: Register to readback. - required: false - default: same as register - type: string - register_type: - description: Modbus register types are holding or input. - required: false - default: holding - type: string - state_on: - description: Register value when switch is on. - required: false - default: same as command_on - type: integer - state_off: - description: Register value when switch is off. - required: false - default: same as command_off - type: integer -{% endconfiguration %} - -It's possible to change the default 30 seconds scan interval for the switch state updates as shown in the [Platform options](/docs/configuration/platform_options/#scan-interval) documentation. - -### Full example - -Example switches, for which the state is polled from Modbus every 10 seconds. - -```yaml -switch: - platform: modbus - scan_interval: 10 - coils: - - name: Switch1 - hub: hub1 - slave: 1 - coil: 13 - - name: Switch2 - hub: hub1 - slave: 2 - coil: 14 -``` diff --git a/source/_redirects b/source/_redirects index a1fe817cb24..4ad849a4135 100644 --- a/source/_redirects +++ b/source/_redirects @@ -1073,14 +1073,19 @@ /components/xiaomi /integrations/xiaomi_aqara /integrations/air_quality.xiaomi_miio /integrations/xiaomi_miio /integrations/alarm_control_panel.xiaomi_miio /integrations/xiaomi_miio +/integrations/binary_sensor.modbus /integrations/modbus +/integrations/climate.modbus /integrations/modbus +/integrations/cover.modbus /integrations/modbus /integrations/fan.xiaomi_miio /integrations/xiaomi_miio /integrations/light.xiaomi_miio /integrations/xiaomi_miio +/integrations/lovelace /lovelace /integrations/remote.xiaomi_miio /integrations/xiaomi_miio /integrations/sensor.websocket_api /integrations/websocket_api +/integrations/sensor.modbus /integrations/modbus /integrations/sensor.xiaomi_miio /integrations/xiaomi_miio +/integrations/switch.modbus /integrations/modbus /integrations/switch.xiaomi_miio /integrations/xiaomi_miio /integrations/vacuum.xiaomi_miio /integrations/xiaomi_miio -/integrations/lovelace /lovelace # Renaming components to integrations /components /integrations From 162789f89f8db08b808b75ea562dbdb1b70e5739 Mon Sep 17 00:00:00 2001 From: Jesse Campbell Date: Mon, 29 Mar 2021 03:44:06 -0400 Subject: [PATCH 50/90] New services for managing lock codes on ZHA Zigbee locks (#16947) --- source/_integrations/zha.markdown | 35 ++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/source/_integrations/zha.markdown b/source/_integrations/zha.markdown index 512ce695566..1dc4f67d97b 100644 --- a/source/_integrations/zha.markdown +++ b/source/_integrations/zha.markdown @@ -252,12 +252,45 @@ from the same group: ### Service `zha.remove` -This service remove an existing device from the network. +This service removes an existing device from the network. | Data | Optional | Description | | ---- | ---- | ----------- | | `ieee` | no | IEEE address of the device to remove +### Service `zha.set_lock_user_code` + +This service sets a lock code on a Zigbee lock. + +| Data | Optional | Description | +| --------- | ---- | ----------- | +| `code_slot` | no | Which lock code slot to store the code. Ex. 1-32 will work for Kwikset 954 +| `user_code` | no | Code to set on the lock. Ex. Kwikset accepts numbers 4-8 digits in length + +### Service `zha.clear_lock_user_code` + +This service clears a lock code from a Zigbee lock. + +| Data | Optional | Description | +| --------- | ---- | ----------- | +| `code_slot` | no | Which lock code slot to clear + +### Service `zha.enable_lock_user_code` + +This service enables a lock code on a Zigbee lock. + +| Data | Optional | Description | +| --------- | ---- | ----------- | +| `code_slot` | no | Which lock code slot to enable + +### Service `zha.disable_lock_user_code` + +This service disables a lock code on a Zigbee lock. + +| Data | Optional | Description | +| --------- | ---- | ----------- | +| `code_slot` | no | Which lock code slot to disable + ## Adding devices To add a new device: From 4e11ce33180e3d265f4a7d5324330afc95808d5c Mon Sep 17 00:00:00 2001 From: William Scanlon Date: Mon, 29 Mar 2021 04:14:56 -0400 Subject: [PATCH 51/90] Updated econet.markdown for climate updates (#16440) Co-authored-by: Franck Nijhof Co-authored-by: Franck Nijhof --- source/_integrations/econet.markdown | 30 +++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/source/_integrations/econet.markdown b/source/_integrations/econet.markdown index e5360fd0565..de6cc6b9b82 100644 --- a/source/_integrations/econet.markdown +++ b/source/_integrations/econet.markdown @@ -2,6 +2,9 @@ title: Rheem EcoNet Products description: Instructions on how to integrate Rheem EcoNet water heaters into Home Assistant. ha_category: + - Binary Sensor + - Climate + - Sensor - Water Heater ha_release: 0.61 ha_iot_class: Cloud Push @@ -16,6 +19,31 @@ ha_platforms: - water_heater --- -The `econet` water heater platform is consuming the information provided by a [EcoNet enabled Rheem water heater](https://www.rheem.com/EcoNet/Home). This platform allows you to set the temperature, the operation mode, and away mode. It also provides access to several device sensors depending on your model of water heater. +The EcoNet integration is consuming the information provided by a [EcoNet enabled Rheem water heater or thermostat](https://www.rheem.com/EcoNet/Home). {% include integrations/config_flow.md %} + +## Platforms + +EcoNet devices may be represented by one or more platforms. + +- [Binary Sensor](#binary-sensor) +- [Climate](#climate) +- [Sensor](#sensor) +- [Water Heater](#water-heater) + +### Binary Sensor + +The EcoNet Binary Sensor platform lets you view binary states of sensors associated with your EcoNet thermostat or water heater. For example, if the device is currently running. + +### Climate + +The EcoNet Climate platform lets you control your EcoNet thermostat. Multi-zone HVAC systems will have 1 Climate entity per zone. + +### Sensor + +The EcoNet Sensor platform lets you view sensors associated with your EcoNet thermostat or water heater. For example, alert count or available hot water. + +### Water Heater + +The EcoNet Water Heater platform lets you control your EcoNet water heater. Water Heaters do not report the current water temperature. From 8289a016af49fae9fed1d208ffefb35926495435 Mon Sep 17 00:00:00 2001 From: plomosits Date: Mon, 29 Mar 2021 10:17:07 +0200 Subject: [PATCH 52/90] Improve Docker and Kubernetes support for KNX (#17095) --- source/_integrations/knx.markdown | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/_integrations/knx.markdown b/source/_integrations/knx.markdown index 442a7daf413..3ec42d0378d 100644 --- a/source/_integrations/knx.markdown +++ b/source/_integrations/knx.markdown @@ -134,6 +134,11 @@ local_ip: description: IP address of the local interface. type: string required: false +route_back: + description: When True the KNXnet/IP Server shall use the IP address and the port number from the IP package received as the target IP address or port number for the response to the KNXnet/IP Client (for NAT / Docker). + type: boolean + default: false + required: false {% endconfiguration %} ### Routing From b304c0f3a3ac2cf76ef133c6b1e44eb85f7509b4 Mon Sep 17 00:00:00 2001 From: chemaaa <187996+chemaaa@users.noreply.github.com> Date: Mon, 29 Mar 2021 11:08:01 +0200 Subject: [PATCH 53/90] Add Legrand Home+ Control Integration document (#16644) Co-authored-by: Klaas Schoute Co-authored-by: Franck Nijhof --- .../_integrations/home_plus_control.markdown | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 source/_integrations/home_plus_control.markdown diff --git a/source/_integrations/home_plus_control.markdown b/source/_integrations/home_plus_control.markdown new file mode 100644 index 00000000000..e1e197ad441 --- /dev/null +++ b/source/_integrations/home_plus_control.markdown @@ -0,0 +1,89 @@ +--- +title: Legrand Home+ Control +description: Instructions on how to integrate Legrand Home+ Control into Home Assistant. +ha_category: + - Switch +ha_release: 2021.4 +ha_iot_class: Cloud Polling +ha_codeowners: + - '@chemaaa' +ha_config_flow: true +ha_domain: home_plus_control +--- + +The Home+ Control integration platform allows you to control a range of Legrand in-wall switches and power outlets that have smart home functionality thanks to their "with Netatmo" capabilities. + +This integration works against the Home+ Control API, which is one of the many APIs offered through the [*Works with Legrand*](https://developer.legrand.com/) program. The API is capable of managing "Legrand/Btcino with Netatmo" devices, such as light switches, power outlets and rolling shutters. + +The devices that this API can manage are offered in different designs across different countries. The details of these can be found [here](https://developer.legrand.com/solutions/wiring-devices-with-netatmo/). + +This Home+ Control integration for Home Assistant currently has support for the following devices: +- Light switches +- Power outlets + +In both cases, the devices are modeled as on/off switches within Home Assistant. + +This integration has been tested to work with the following range of Legrand products: +- Valena Next™ with Netatmo + + +## Authentication + +Before you are able to configure the Legrand Home + Control integration into Home Assistant, you must register with the *Works with Legrand* platform. + +These Legrand APIs rely on Oauth2 authentication, so you must follow these steps to obtain the necessary authentication parameters: + +1. Register an account at . +2. Create a subscription to the *Starter Kit* (currently the only subscription available) and this will generate your `SUBSCRIPTION_KEY`. +3. Register an application, where you will have to define a name, a redirect URL and the scopes of your application. When selecting the scopes, be sure to include all of the `.read` scopes, as well as the `light.write` and `plug.write` scopes to be able to control these modules from the integration. + +Once the registered application is confirmed, you should receive an email containing the `CLIENT_IDENTIFIER` and the `CLIENT_SECRET` which you will be using to set up the authentication flows. The application confirmation email is usually received within a few hours of having issued the request. + +Finally, to set up Oauth2 authentication in Home Assistant you should add the following information to your `configuration.yaml` file: + +```yaml +# Example configuration.yaml entry +home_plus_control: + client_id: CLIENT_IDENTIFIER + client_secret: CLIENT_SECRET + subscription_key: SUBSCRIPTION_KEY +``` + +{% configuration %} +client_id: + description: Client identifier for your registered application on the *Works with Legrand* platform. Received via email. + required: true + type: string +client_secret: + description: Client secret for your registered application on the *Works with Legrand* platform. Received via email. + required: true + type: string +subscription_key: + description: Subscription identifier for your registered account on the *Works with Legrand* platform. Provided upon registration. + required: true + type: string +{% endconfiguration %} + + +At this point, you are now ready to add the Home+ Control integration to your Home Assistant instance as described in the [Configuration](#configuration) section. + + +{% include integrations/config_flow.md %} + + +## API Nomenclature + +Within the context of the Home+ Control API you may come across the following terms: + +* *Plant*: This is the term used to represent a *home* that holds the Legrand devices. In practice, a *plant* is represented by the *Legrand Home+ Control* gateway that acts as the central hub of the rest of the devices in the home network (uses Zigbee). +* *Module*: This is the term used to represent a generic device within the *plant*, i.e., a light, a plug, a remote, etc. +* *Light*: This is the term used to represent a light switch (or a micro-module). It is not modeled as your usual light entity because there are no brightness, color, etc. controls. It is modeled as an on/off switch. +* *Plug*: This is the term used to represent a power outlet. + +Other devices that are mentioned in the API, but that are not currently supported by this integration are: *remotes* (wireless switches), *heaters* and *automations*. + +## API Limitations + +As described in the [authentication](#authentication) section, this integration requires you to set up a subscription in the *Works with Legrand* platform. + +Currently, end-users only have access to the *Starter Kit* subscription which has a major limitation in the number of allowed API requests that are allowed - only 500 API calls per day (counter is reset at 00:00 every day). If this daily quota is ever exceeded, the API will report `403 Forbidden` HTTP responses. From af3135df7f20618789e91a2e9142b4342a9d5adf Mon Sep 17 00:00:00 2001 From: Martidjen Date: Mon, 29 Mar 2021 12:50:06 +0200 Subject: [PATCH 54/90] Update openthem_gw.markdown (#16904) --- source/_integrations/opentherm_gw.markdown | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/source/_integrations/opentherm_gw.markdown b/source/_integrations/opentherm_gw.markdown index cff008c9358..9caa472f8ce 100644 --- a/source/_integrations/opentherm_gw.markdown +++ b/source/_integrations/opentherm_gw.markdown @@ -59,16 +59,14 @@ The precision and floor_temperature settings that were supported in configuratio The OpenTherm Gateway can be further configured through the integration settings in the web interface The following options are available: -{% configuration %} -Precision: - description: "The desired precision for this device. Can be used to match your actual thermostat's precision. Set to `0` to use the default value for your unit preference." - type: float - default: "`0.5` for Celsius and `1.0` for Fahrenheit." +{% configuration_basic %} +Read Precision: + description: "The desired read precision for this device. Used to display the current temperature on the climate entity. Can be used to match your actual thermostat's precision. Set to `0` to use the default value for your unit preference." +Set Precision: + description: "The desired set precision for this device. Used as step size for setting temperature setpoint from the climate entity. Can be used to match your actual thermostat's precision. Set to `0` to use the default value for your unit preference." Floor Temperature: description: "Some thermostats round all temperatures down to the lower value according to their precision. Default behavior for Home Assistant is to round temperatures to the nearest value. Enable this setting to override this behavior and round to the lower value according to the configured precision." - type: boolean - default: Disabled -{% endconfiguration %} +{% endconfiguration_basic %} ## Services From 5b68cc0898634f9980eecf678ea3841751dab33a Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 29 Mar 2021 15:35:38 +0200 Subject: [PATCH 55/90] Revert "Revert "Support preset modes and percentage for mqtt fan (#17048)"" This reverts commit 29ac6acf328e622538609f40a4e410254edd21d1. --- source/_docs/mqtt/discovery.markdown | 9 +++ source/_integrations/fan.mqtt.markdown | 92 ++++++++++++++------------ 2 files changed, 60 insertions(+), 41 deletions(-) diff --git a/source/_docs/mqtt/discovery.markdown b/source/_docs/mqtt/discovery.markdown index 74311158e5c..ecd61b01e64 100644 --- a/source/_docs/mqtt/discovery.markdown +++ b/source/_docs/mqtt/discovery.markdown @@ -160,6 +160,9 @@ Supported abbreviations: 'osc_cmd_t': 'oscillation_command_topic', 'osc_stat_t': 'oscillation_state_topic', 'osc_val_tpl': 'oscillation_value_template', + 'pct_cmd_t': 'percentage_command_topic', + 'pct_stat_t': 'percentage_state_topic', + 'pct_val_tpl': 'percentage_value_template', 'pl': 'payload', 'pl_arm_away': 'payload_arm_away', 'pl_arm_home': 'payload_arm_home', @@ -196,6 +199,10 @@ Supported abbreviations: 'pow_cmd_t': 'power_command_topic', 'pow_stat_t': 'power_state_topic', 'pow_stat_tpl': 'power_state_template', + 'pr_mode_cmd_t': 'preset_mode_command_topic', + 'pr_mode_stat_t': 'preset_mode_state_topic', + 'pr_mode_val_tpl': 'preset_mode_value_template', + 'pr_modes': 'preset_modes', 'r_tpl': 'red_template', 'ret': 'retain', 'rgb_cmd_tpl': 'rgb_command_template', @@ -211,6 +218,8 @@ Supported abbreviations: 'pos_tpl': 'position_template', 'spd_cmd_t': 'speed_command_topic', 'spd_stat_t': 'speed_state_topic', + 'spd_rng_min': 'speed_range_min', + 'spd_rng_max': 'speed_range_max', 'spd_val_tpl': 'speed_value_template', 'spds': 'speeds', 'src_type': 'source_type', diff --git a/source/_integrations/fan.mqtt.markdown b/source/_integrations/fan.mqtt.markdown index bd53656f198..96a0078e134 100644 --- a/source/_integrations/fan.mqtt.markdown +++ b/source/_integrations/fan.mqtt.markdown @@ -132,21 +132,6 @@ payload_available: required: false type: string default: online -payload_high_speed: - description: The payload that represents the fan's high speed. - required: false - type: string - default: high -payload_low_speed: - description: The payload that represents the fan's low speed. - required: false - type: string - default: low -payload_medium_speed: - description: The payload that represents the fan's medium speed. - required: false - type: string - default: medium payload_not_available: description: The payload that represents the unavailable state. required: false @@ -172,6 +157,35 @@ payload_oscillation_on: required: false type: string default: oscillate_on +percentage_command_topic: + description: The MQTT topic to publish commands to change the fan speed state based on a percentage. + required: false + type: string +percentage_state_topic: + description: The MQTT topic subscribed to receive fan speed based on percentage. + required: false + type: string +percentage_value_template: + description: Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract a value from fan percentage speed. + required: false + type: string +preset_mode_command_topic: + description: The MQTT topic to publish commands to change the preset mode. + required: false + type: string +preset_mode_state_topic: + description: The MQTT topic to publish commands to change the preset mode. + required: false + type: string +preset_mode_value_template: + description: Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract a value from the preset_mode payload. + required: false + type: string +preset_modes: + description: List of preset modes this fan is capable of running at. Common examples include `auto`, `smart`, `whoosh`, `eco` and `breeze`. + required: false + type: [list] + default: [] qos: description: The maximum QoS level of the state topic. required: false @@ -182,22 +196,16 @@ retain: required: false type: boolean default: true -speed_command_topic: - description: The MQTT topic to publish commands to change speed state. +speed_range_min: + description: The minimum of numeric output range (`off` not included, so `speed_range_min` - 1 represents 0%). required: false - type: string -speed_state_topic: - description: The MQTT topic subscribed to receive speed state updates. + type: integer + default: 1 +speed_range_max: + description: The maximum of numeric output range (representing 100%). required: false - type: string -speed_value_template: - description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract a value from the speed payload." - required: false - type: string -speeds: - description: "List of speeds this fan is capable of running at. Valid entries are `off`, `low`, `medium` and `high`." - required: false - type: [string, list] + type: integer + default: 100 state_topic: description: The MQTT topic subscribed to receive state updates. required: false @@ -224,10 +232,10 @@ In this section you find some real-life examples of how to use this fan. ### Full configuration -The example below shows a full configuration for a MQTT fan. +The example below shows a full configuration for a MQTT fan using percentage and preset modes. ```yaml -# Example configuration.yaml entry +# Example using percentage based speeds with preset modes configuration.yaml fan: - platform: mqtt name: "Bedroom Fan" @@ -235,19 +243,21 @@ fan: command_topic: "bedroom_fan/on/set" oscillation_state_topic: "bedroom_fan/oscillation/state" oscillation_command_topic: "bedroom_fan/oscillation/set" - speed_state_topic: "bedroom_fan/speed/state" - speed_command_topic: "bedroom_fan/speed/set" + percentage_state_topic: "bedroom_fan/speed/percentage_state" + percentage_command_topic: "bedroom_fan/speed/percentage" + preset_mode_state_topic: "bedroom_fan/speed/preset_mode_state" + preset_mode_command_topic: "bedroom_fan/speed/preset_mode" + preset_modes: + - "auto" + - "smart" + - "whoosh" + - "eco" + - "breeze" qos: 0 payload_on: "true" payload_off: "false" payload_oscillation_on: "true" payload_oscillation_off: "false" - payload_low_speed: "low" - payload_medium_speed: "medium" - payload_high_speed: "high" - speeds: - - "off" - - low - - medium - - high + speed_range_min: 1 + speed_range_max: 100 ``` From 14b2d8515dfa707dbb0ed465d2adf810f28ed8b6 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 29 Mar 2021 19:18:15 +0200 Subject: [PATCH 56/90] Add support for Selectors in Script service fields (#17171) --- source/_integrations/script.markdown | 41 +++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/source/_integrations/script.markdown b/source/_integrations/script.markdown index c41ef183857..b3f69226938 100644 --- a/source/_integrations/script.markdown +++ b/source/_integrations/script.markdown @@ -11,7 +11,7 @@ ha_domain: script ha_iot_class: --- -The `script` integration allows users to specify a sequence of actions to be executed by Home Assistant. These are run when you turn the script on. The script integration will create an entity for each script and allow them to be controlled via services. +The script integration allows users to specify a sequence of actions to be executed by Home Assistant. These are run when you turn the script on. The script integration will create an entity for each script and allow them to be controlled via services. ## Configuration @@ -62,21 +62,41 @@ variables: description: The value of the variable. Any YAML is valid. Templates can also be used to pass a value to the variable. type: any fields: - description: "Information about the parameters that the script uses; see the [Passing variables to scripts](#passing-variables-to-scripts) section below. Please note: In order for this description to be displayed in the Services tab of the Developer Tools, the script description must be defined as well." + description: "Information about the script field parameters; see the [Passing variables to scripts](#passing-variables-to-scripts) section below. Please note: In order for this description to be displayed in the Services tab of the Developer Tools, the script description must be defined as well." required: false default: {} type: map keys: - PARAMETER_NAME: - description: A parameter used by this script. + FIELD_NAME: + description: A parameter field used by this script. All sub-options are only used for creating a representation of this script in the UI. type: map keys: + name: + description: The name of this script parameter field. + type: string description: - description: A description of PARAMETER_NAME. + description: A description of this of this script parameter. type: string + advanced: + description: Marks this field as an advanced parameter. This causes it only to be shown in the UI, when the user has advanced mode enabled. + type: boolean + default: false + required: + description: Mark if this field is required. This is a UI only feature. + type: boolean + default: false example: - description: An example value for PARAMETER_NAME. + description: An example value. This will only be shown in table of options available in the Services tab of the Developer Tools. type: string + default: + description: The default value for this field, as shown in the UI. + type: any + selector: + description: > + The [selector](/docs/blueprint/selectors/) to use for this input. A + selector defines how the input is displayed in the frontend UI. + type: selector + required: false mode: description: "Controls what happens when script is invoked while it is still running from one or more previous invocations. See [Script Modes](#script-modes)." required: false @@ -125,8 +145,15 @@ script:  turn_on_entity: group.living_room fields: minutes: + name: Minutes description: "The amount of time to wait before turning on the living room lights" - example: 1 + selector: + number: + min: 0 + max: 60 + step: 1 + unit_of_measurement: minutes + mode: slider # If called again while still running (probably in delay step), start over. mode: restart sequence: From bf2aa1a87b3faef7bd176c40566d4b06d323d8d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 30 Mar 2021 13:39:10 +0200 Subject: [PATCH 57/90] Add analytics integration (#17104) Co-authored-by: Franck Nijhof --- source/_integrations/analytics.markdown | 159 ++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 source/_integrations/analytics.markdown diff --git a/source/_integrations/analytics.markdown b/source/_integrations/analytics.markdown new file mode 100644 index 00000000000..ea825bea113 --- /dev/null +++ b/source/_integrations/analytics.markdown @@ -0,0 +1,159 @@ +--- +title: Analytics +description: Share system analytics and diagnostics +ha_category: + - Other +ha_release: 2021.4 +ha_iot_class: Cloud Push +ha_quality_scale: internal +ha_codeowners: + - '@home-assistant/core' +ha_domain: analytics +--- + +The Analytics integration will collect information about the running Home Assistant instance and its environment. The information sent depends on what sections you enable in the integration, by default nothing is enabled. The different sections can be controlled in the UI under **{% my general title="Configuration >> General" %}**. + +**{% my general badge %}** + +When enabled the integration will send data 15 minutes after each start, and every 24h after startup. When the data is sent the full payload will be printed to your log. + +The collected data is available to the public at + +## Configuration + +This integration is by default enabled, unless you've disabled or removed the [`default_config:`](/integrations/default_config/) line from your configuration. If that is the case, the following example shows you how to enable this integration manually, just enabling the integration will **not** make it sent analytics: + +```yaml +analytics: +``` + +## Basic analytics + +This includes: + +- The UUID of your system +- The version of your system +- The installation type of your system + +If your system includes the Supervisor this will also contain: + +- A boolean that indicates if the system is supported +- A boolean that indicates if the system is healthy + +{% details Example payload %} + +```json +{ + "huuid": "12a3456bc78d90123ef4567g789012h3", + "version": "2021.4.0", + "installation_type": "Home Assistant OS", + "supervisor": { + "healthy": true, + "supported": true + } +} +``` + +{% enddetails %} + +## Usage analytics + +You need to enable [basic analytics](#basic-analytics) to be able to enable this. + +This includes: + +- The names of all your integrations + +If your system include the Supervisor this will also contain: + +- The name of all installed add-ons +- The version of all installed add-ons +- The state of protection mode of all installed add-ons +- The state of the auto update toggle of all installed add-ons + +{% details Example payload %} + +```json +{ + "huuid": "12a3456bc78d90123ef4567g789012h3", + "version": "2021.4.0", + "installation_type": "Home Assistant OS", + "supervisor": { + "healthy": true, + "supported": true + }, + "integrations": ["awesome_integration"], + "addons": [ + { + "slug": "awesome_addon", + "protected": true, + "version": "1.0.0", + "auto_update": false + } + ] +} +``` + +{% enddetails %} + +## Statistics + +You need to enable [basic analytics](#basic-analytics) to be able to enable this. + +This includes: + +- Number of integrations +- Number of users +- Number of entities +- Number of automations + +If your system include the Supervisor this will also contain: + +- Number of installed add-ons + +{% details Example payload %} + +```json +{ + "huuid": "12a3456bc78d90123ef4567g789012h3", + "version": "2021.4.0", + "installation_type": "Home Assistant OS", + "supervisor": { + "healthy": true, + "supported": true + }, + "state_count": 1, + "automation_count": 2, + "integration_count": 3, + "addon_count": 4, + "user_count": 5 +} +``` + +{% enddetails %} + +## Diagnostics + +This is not sent to the same [Receiver](#receiver) as the rest of the information enabled with this integration. Crash reports are sent to [Sentry](https://sentry.io/welcome/). This data will not be made public and will only be available to a few core developers. + +For now, this is only being done for events inside the Supervisor if your system has that. If this changes to include other parts of the ecosystem it will be mentioned in the release notes and the documentation here will be updated. + +## Receiver + +The receiver that the payloads are sent to is running as a [CloudFlare Worker](https://workers.cloudflare.com/) and the code for that can be inspected in the [home-assistant/analytics repository](https://github.com/home-assistant/analytics.home-assistant.io). + +## Storage and usage + +When your installation sends a payload, that payload includes a unique identifier, this identifier is used to make sure that future payload updates, only change information from your installation. +The data is stored in CloudFlare's KV (Key-Value) store for the [Receiver](#receiver), and will be stored for a maximum of 60 days since the last update. + +This is an example of how the information is stored: +{% configuration_basic %} +"huuid:12a3456bc78d90123ef4567g789012h3": + description: "{'version': '2021.4.0', 'installation_type': 'Home Assistant OS'}" + +{% endconfiguration_basic %} + +Like all other websites you visit, the IP address and client information that sent the request will be visible to the remote server, this, however, is not stored by us (you are more than welcome to inspect [the code that receives the data](https://github.com/home-assistant/analytics.home-assistant.io)), CloudFlare will keep a log of all interactions, [see their privacy policy for more details about that](https://www.cloudflare.com/privacypolicy/) + +The data will be used to display the information on and to analyze how users are using Home Assistant. This allows for workload prioritizing to focus resources on improving the areas that are most important to our users. From 7033b37d5709d275f00e0cd2c89eeaba6feeb1fc Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 30 Mar 2021 08:44:10 -0400 Subject: [PATCH 58/90] Add documentation for zwave_js.set_value service (#17177) --- source/_integrations/zwave_js.markdown | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source/_integrations/zwave_js.markdown b/source/_integrations/zwave_js.markdown index 5cceeace7a9..abe5f86a0cd 100644 --- a/source/_integrations/zwave_js.markdown +++ b/source/_integrations/zwave_js.markdown @@ -113,6 +113,21 @@ This service will refresh the value(s) for an entity. This service will generate | `entity_id` | yes | Entity or list of entities to refresh values for. | | `refresh_all_values` | no | Whether all values should be refreshed. If `false`, only the primary value will be refreshed. If `true`, all watched values will be refreshed. | +### Service `zwave_js.set_value` + +This service will set a value on a Z-Wave device. It is for advanced use cases where you need to modify the state of a node and can't do it using native Home Assistant entity functionality. Be warned that correctly using this service requires advanced knowledge of Z-Wave. The service provides minimal validation and blindly calls the Z-Wave JS API, so if you are having trouble using it, it is likely because you are providing an incorrect value somewhere. To set a config parameter, you should use the `zwave_js.set_config_parameter` or `zwave_js.bulk_set_partial_config_parameters` services instead of this one. + +| Service Data Attribute | Required | Description | +|------------------------ |---------- |-------------------------------------------------------------------------------------------------------------------------------------------------- | +| `entity_id` | no | Entity (or list of entities) to set the configuration parameter on. At least one `entity_id` or `device_id` must be provided. | +| `device_id` | no | ID of device to set the configuration parameter on. At least one `entity_id` or `device_id` must be provided. | +| `command_class` | yes | ID of Command Class that you want to set the value for. | +| `property` | yes | ID of Property that you want to set the value for. | +| `property_key` | no | ID of Property Key that you want to set the value for. | +| `endpoint` | no | ID of Endpoint that you want to set the value for. | +| `value` | yes | The new value that you want to set. | +| `wait_for_result` | no | Boolean that indicates whether or not to wait for a response from the node. If not included in the payload, the integration will decide whether to wait or not. If set to `true`, note that the service call can take a while if setting a value on an asleep battery device. | + ### Service `zwave_js.set_lock_usercode` This service will set the usercode of a lock to X at code slot Y. From c79e162f6f3727236ece61a4e9ec362eef182d22 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Tue, 30 Mar 2021 14:47:25 +0200 Subject: [PATCH 59/90] Command templates for mqtt fan (#17173) --- source/_docs/mqtt/discovery.markdown | 11 ++----- source/_integrations/fan.mqtt.markdown | 40 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/source/_docs/mqtt/discovery.markdown b/source/_docs/mqtt/discovery.markdown index ecd61b01e64..471ec71cd74 100644 --- a/source/_docs/mqtt/discovery.markdown +++ b/source/_docs/mqtt/discovery.markdown @@ -158,9 +158,11 @@ Supported abbreviations: 'on_cmd_type': 'on_command_type', 'opt': 'optimistic', 'osc_cmd_t': 'oscillation_command_topic', + 'osc_cmd_tpl': 'oscillation_command_template', 'osc_stat_t': 'oscillation_state_topic', 'osc_val_tpl': 'oscillation_value_template', 'pct_cmd_t': 'percentage_command_topic', + 'pct_cmd_tpl': 'percentage_command_template', 'pct_stat_t': 'percentage_state_topic', 'pct_val_tpl': 'percentage_value_template', 'pl': 'payload', @@ -172,16 +174,12 @@ Supported abbreviations: 'pl_cln_sp': 'payload_clean_spot', 'pl_cls': 'payload_close', 'pl_disarm': 'payload_disarm', - 'pl_hi_spd': 'payload_high_speed', 'pl_home': 'payload_home', 'pl_lock': 'payload_lock', 'pl_loc': 'payload_locate', - 'pl_lo_spd': 'payload_low_speed', - 'pl_med_spd': 'payload_medium_speed', 'pl_not_avail': 'payload_not_available', 'pl_not_home': 'payload_not_home', 'pl_off': 'payload_off', - 'pl_off_spd': 'payload_off_speed', 'pl_on': 'payload_on', 'pl_open': 'payload_open', 'pl_osc_off': 'payload_oscillation_off', @@ -200,6 +198,7 @@ Supported abbreviations: 'pow_stat_t': 'power_state_topic', 'pow_stat_tpl': 'power_state_template', 'pr_mode_cmd_t': 'preset_mode_command_topic', + 'pr_mode_cmd_tpl': 'preset_mode_command_template', 'pr_mode_stat_t': 'preset_mode_state_topic', 'pr_mode_val_tpl': 'preset_mode_value_template', 'pr_modes': 'preset_modes', @@ -216,12 +215,8 @@ Supported abbreviations: 'set_pos_t': 'set_position_topic', 'pos_t': 'position_topic', 'pos_tpl': 'position_template', - 'spd_cmd_t': 'speed_command_topic', - 'spd_stat_t': 'speed_state_topic', 'spd_rng_min': 'speed_range_min', 'spd_rng_max': 'speed_range_max', - 'spd_val_tpl': 'speed_value_template', - 'spds': 'speeds', 'src_type': 'source_type', 'stat_clsd': 'state_closed', 'stat_closing': 'state_closing', diff --git a/source/_integrations/fan.mqtt.markdown b/source/_integrations/fan.mqtt.markdown index 96a0078e134..50eafc25bad 100644 --- a/source/_integrations/fan.mqtt.markdown +++ b/source/_integrations/fan.mqtt.markdown @@ -56,6 +56,10 @@ availability_topic: description: The MQTT topic subscribed to receive availability (online/offline) updates. Must not be used together with `availability`. required: false type: string +command_template: + description: Defines a [template](/docs/configuration/templating/#processing-incoming-data) to generate the payload to send to `command_topic`. + required: false + type: template command_topic: description: The MQTT topic to publish commands to change the fan state. required: true @@ -115,6 +119,10 @@ optimistic: required: false type: boolean default: "`true` if no state topic defined, else `false`." +oscillation_command_template: + description: Defines a [template](/docs/configuration/templating/#processing-incoming-data) to generate the payload to send to `oscillation_command_topic`. + required: false + type: template oscillation_command_topic: description: The MQTT topic to publish commands to change the oscillation state. required: false @@ -157,6 +165,10 @@ payload_oscillation_on: required: false type: string default: oscillate_on +percentage_command_template: + description: Defines a [template](/docs/configuration/templating/#processing-incoming-data) to generate the payload to send to `percentage_command_topic`. + required: false + type: template percentage_command_topic: description: The MQTT topic to publish commands to change the fan speed state based on a percentage. required: false @@ -169,6 +181,10 @@ percentage_value_template: description: Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract a value from fan percentage speed. required: false type: string +preset_mode_command_template: + description: Defines a [template](/docs/configuration/templating/#processing-incoming-data) to generate the payload to send to `preset_mode_command_topic`. + required: false + type: template preset_mode_command_topic: description: The MQTT topic to publish commands to change the preset mode. required: false @@ -261,3 +277,27 @@ fan: speed_range_min: 1 speed_range_max: 100 ``` + +This example demonstrates how to use command templates with JSON output. + +```yaml +# Example configuration.yaml +# Example using command templates +fan: + - platform: mqtt + name: "Bedroom Fan" + command_topic: "bedroom_fan/on/set" + command_template: "{ state: '{{ value }}'}" + oscillation_command_topic: "bedroom_fan/oscillation/set" + oscillation_command_template: "{ oscillation: '{{ value }}'}" + percentage_command_topic: "bedroom_fan/speed/percentage" + percentage_command_template: "{ percentage: {{ value }}}" + preset_mode_command_topic: "bedroom_fan/speed/preset_mode" + preset_mode_command_template: "{ preset_mode: '{{ value }}'}" + preset_modes: + - "auto" + - "smart" + - "whoosh" + - "eco" + - "breeze" +``` From 8ebbbea70100a47065e9530414ca3c18d8e42c83 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 30 Mar 2021 09:46:09 -0400 Subject: [PATCH 60/90] Add documentation for zwave_js.bulk_set_partial_config_parameters service (#17127) Co-authored-by: Franck Nijhof --- source/_integrations/zwave_js.markdown | 65 +++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/source/_integrations/zwave_js.markdown b/source/_integrations/zwave_js.markdown index abe5f86a0cd..b68ec215ca6 100644 --- a/source/_integrations/zwave_js.markdown +++ b/source/_integrations/zwave_js.markdown @@ -57,7 +57,7 @@ Advanced users: Make sure that the server started successfully by inspecting the ### Service `zwave_js.set_config_parameter` -This service will update a configuration parameter. At this time, it is not possible to update multiple partial parameters in a single call, but we hope to add support for that in the future. +This service will update a configuration parameter. To update multiple partial parameters in a single call, use the `zwave_js.bulk_set_partial_config_parameters` service. | Service Data Attribute | Required | Description | |------------------------ |----------- |------------------------------------------------------------------------------------------------------------------------------------------- | @@ -72,6 +72,7 @@ This service will update a configuration parameter. At this time, it is not poss Let's use parameter 31 for [this device](https://devices.zwave-js.io/?jumpTo=0x000c:0x0203:0x0001:0.0) as an example to show examples of different ways that the `LED 1 Blink Status (bottom)` partial parameter can be set. Note that in places where we are using different values for the same key, the different values are interchangeable across the examples. We can, for instance, use `1` or `Blink` interchangeably for the `value` in all of the examples. Example 1: + ```yaml service: zwave_js.set_config_parameter target: @@ -83,6 +84,7 @@ data: ``` Example 2: + ```yaml service: zwave_js.set_config_parameter target: @@ -94,6 +96,7 @@ data: ``` Example 3: + ```yaml service: zwave_js.set_config_parameter target: @@ -104,6 +107,66 @@ data: value: "Blink" ``` +### Service `zwave_js.bulk_set_partial_config_parameters` + +This service will bulk set multiple partial configuration parameters. Be warned that correctly using this service requires advanced knowledge of Z-Wave to use correctly. + +| Service Data Attribute | Required | Description | +|------------------------ |----------- |------------------------------------------------------------------------------------------------------------------------------------------- | +| `entity_id` | no | Entity (or list of entities) to set the configuration parameter on. At least one `entity_id` or `device_id` must be provided. | +| `device_id` | no | ID of device to set the configuration parameter on. At least one `entity_id` or `device_id` must be provided. | +| `parameter` | yes | The parameter number or the name of the property. The name of the property is case sensitive. | +| `value` | yes | Either the raw integer value that you want to set for the entire parameter, or a dictionary where the keys are the bitmasks (in integer or hex form) and the values are the value you want to set on each partial. Note that when using a dictionary, and bitmasks that are not provided will be set to their currently cached values. | + +#### Examples of bulk setting partial parameter values + +Let's use parameter 21 for [this device](https://devices.zwave-js.io/?jumpTo=0x031e:0x000a:0x0001:0.0) as an example to show how partial parameters can be bulk set. In this case, we want to set `0xff` to `127`, `0x7f00` to `10`, and `0x8000` to `1` (or the raw value of `4735`). + +
    + +When using the dictionary format to map the partial parameter to values, the cached values for the missing partial parameters will be used. So in examples 2 and 3, the service would use the cached value for partial parameters `0xff0000`, `0x3f000000`, and `0x40000000` because new values haven't been specified. If you send the raw integer value, it is assumed that you have calculated the full value, so in example 1, partial parameters `0xff0000`, `0x3f000000`, and `0x40000000` would all be set to `0`. + +
    + +Example 1: + +```yaml +service: zwave_js.bulk_set_partial_config_parameters +target: + entity_id: switch.fan +data: + parameter: 21 + value: 4735 +``` + +Example 2: + +```yaml +service: zwave_js.bulk_set_partial_config_parameters +target: + entity_id: switch.fan +data: + parameter: 21 + value: + 0xff: 127 + 0x7f00: 10 + 0x8000: 1 +``` + +Example 3: + +```yaml +service: zwave_js.bulk_set_partial_config_parameters +target: + entity_id: switch.fan +data: + parameter: 21 + value: + 255: 127 + 32512: 10 + 32768: 1 +``` + ### Service `zwave_js.refresh_value` This service will refresh the value(s) for an entity. This service will generate extra traffic on your Z-Wave network and should be used sparingly. Updates from devices on battery may take some time to be received. From 071a69b7cf62c1769269337afd28cbc016f653a3 Mon Sep 17 00:00:00 2001 From: Martidjen Date: Tue, 30 Mar 2021 15:47:24 +0200 Subject: [PATCH 61/90] Add description for Setpoint Override Mode (#17169) --- source/_integrations/opentherm_gw.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/_integrations/opentherm_gw.markdown b/source/_integrations/opentherm_gw.markdown index 9caa472f8ce..dc815ca4fb6 100644 --- a/source/_integrations/opentherm_gw.markdown +++ b/source/_integrations/opentherm_gw.markdown @@ -64,6 +64,8 @@ Read Precision: description: "The desired read precision for this device. Used to display the current temperature on the climate entity. Can be used to match your actual thermostat's precision. Set to `0` to use the default value for your unit preference." Set Precision: description: "The desired set precision for this device. Used as step size for setting temperature setpoint from the climate entity. Can be used to match your actual thermostat's precision. Set to `0` to use the default value for your unit preference." +Temporary Setpoint Override Mode: + description: "The desired setpoint override mode. When Temporary Setpoint Override Mode is set to on, the thermostat will be able to cancel the setpoint override after a program change. When the option is set to off, the Setpoint Override Mode will be ‘Constant’ and a manual temperature adjustment on the thermostat is needed to cancel the setpoint override." Floor Temperature: description: "Some thermostats round all temperatures down to the lower value according to their precision. Default behavior for Home Assistant is to round temperatures to the nearest value. Enable this setting to override this behavior and round to the lower value according to the configured precision." {% endconfiguration_basic %} From 23659f766c92f7993138d090c7ef64a78a261119 Mon Sep 17 00:00:00 2001 From: Fredrik Erlandsson Date: Tue, 30 Mar 2021 15:48:16 +0200 Subject: [PATCH 62/90] Updates for pypoint 2.1.0 (#17098) --- source/_integrations/point.markdown | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/_integrations/point.markdown b/source/_integrations/point.markdown index 1ca4a7fac9f..d18a7b7e8db 100644 --- a/source/_integrations/point.markdown +++ b/source/_integrations/point.markdown @@ -76,16 +76,21 @@ The Point only supports a Arm/Disarm action, so it is only `Arm Away` that is im Each Point exposes the following binary sensors: +- **alarm**: `On` means alarm sound was recognised, `Off` means normal - **battery**: `On` means low, `Off` means normal - **button_press**: `On` means the button was pressed, `Off` means normal - **cold**: `On` means cold, `Off` means normal - **connectivity**: `On` means connected, `Off` means disconnected - **dry**: `On` means too dry, `Off` means normal +- **glass**: `On` means the sound of glass break was detected, `Off` means normal - **heat**: `On` means hot, `Off` means normal - **light**: `On` means light detected, `Off` means no light - **moisture**: `On` means moisture detected (wet), `Off` means no moisture (dry) +- **motion**: `On` means motion was detected, `Off` means no motion +- **noise**: `On` means noise was detected, `Off` means noise levels have gone back to normal - **sound**: `On` means sound detected, `Off` means no sound (clear) -- **tamper**: `On` means the point was removed or attached, `Off` means normal +- **tamper**: `On` means the point was removed, `Off` means normal +- **tamper_old**: `On` means the point was removed or attached, `Off` means normal (this is only supported on some "old" devices)
    From abfb3bddc5644d9be34b8f51cce16ee9dd025a2d Mon Sep 17 00:00:00 2001 From: Kristian Heljas Date: Tue, 30 Mar 2021 16:53:11 +0300 Subject: [PATCH 63/90] Consistent icon support for MQTT entitites (#16785) Implementing PR: https://github.com/home-assistant/core/pull/47165 --- .../_integrations/alarm_control_panel.mqtt.markdown | 4 ++++ source/_integrations/binary_sensor.mqtt.markdown | 4 ++++ source/_integrations/camera.mqtt.markdown | 4 ++++ source/_integrations/climate.mqtt.markdown | 4 ++++ source/_integrations/cover.mqtt.markdown | 4 ++++ source/_integrations/device_tracker.mqtt.markdown | 2 +- source/_integrations/fan.mqtt.markdown | 4 ++++ source/_integrations/light.mqtt.markdown | 12 ++++++++++++ source/_integrations/lock.mqtt.markdown | 4 ++++ source/_integrations/number.mqtt.markdown | 2 +- source/_integrations/sensor.mqtt.markdown | 2 +- source/_integrations/switch.mqtt.markdown | 2 +- source/_integrations/vacuum.mqtt.markdown | 4 ++++ 13 files changed, 48 insertions(+), 4 deletions(-) diff --git a/source/_integrations/alarm_control_panel.mqtt.markdown b/source/_integrations/alarm_control_panel.mqtt.markdown index 895ba5364fe..a543b9baa2e 100644 --- a/source/_integrations/alarm_control_panel.mqtt.markdown +++ b/source/_integrations/alarm_control_panel.mqtt.markdown @@ -125,6 +125,10 @@ device: description: "Identifier of a device that routes messages between this device and Home Assistant. Examples of such devices are hubs, or parent devices of a sub-device. This is used to show device topology in Home Assistant." required: false type: string +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`. Usage example can be found in [MQTT sensor](/integrations/sensor.mqtt/#json-attributes-template-configuration) documentation." required: false diff --git a/source/_integrations/binary_sensor.mqtt.markdown b/source/_integrations/binary_sensor.mqtt.markdown index be94a14381c..3c3f1dffb70 100644 --- a/source/_integrations/binary_sensor.mqtt.markdown +++ b/source/_integrations/binary_sensor.mqtt.markdown @@ -109,6 +109,10 @@ force_update: required: false type: boolean default: false +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`. Usage example can be found in [MQTT sensor](/integrations/sensor.mqtt/#json-attributes-template-configuration) documentation." required: false diff --git a/source/_integrations/camera.mqtt.markdown b/source/_integrations/camera.mqtt.markdown index 80fd9f0796a..00304a9a52b 100644 --- a/source/_integrations/camera.mqtt.markdown +++ b/source/_integrations/camera.mqtt.markdown @@ -89,6 +89,10 @@ device: description: 'Identifier of a device that routes messages between this device and Home Assistant. Examples of such devices are hubs, or parent devices of a sub-device. This is used to show device topology in Home Assistant.' required: false type: string +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`." required: false diff --git a/source/_integrations/climate.mqtt.markdown b/source/_integrations/climate.mqtt.markdown index 373ae3b2a8b..a3bd1b3ff90 100644 --- a/source/_integrations/climate.mqtt.markdown +++ b/source/_integrations/climate.mqtt.markdown @@ -174,6 +174,10 @@ initial: required: false type: integer default: 21 +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`. Usage example can be found in [MQTT sensor](/integrations/sensor.mqtt/#json-attributes-template-configuration) documentation." required: false diff --git a/source/_integrations/cover.mqtt.markdown b/source/_integrations/cover.mqtt.markdown index 0d72e73249b..6af66bf58d6 100644 --- a/source/_integrations/cover.mqtt.markdown +++ b/source/_integrations/cover.mqtt.markdown @@ -110,6 +110,10 @@ device_class: description: Sets the [class of the device](/integrations/cover/), changing the device state and icon that is displayed on the frontend. required: false type: string +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`. Usage example can be found in [MQTT sensor](/integrations/sensor.mqtt/#json-attributes-template-configuration) documentation." required: false diff --git a/source/_integrations/device_tracker.mqtt.markdown b/source/_integrations/device_tracker.mqtt.markdown index 33eda93ed90..77aeb5a2257 100644 --- a/source/_integrations/device_tracker.mqtt.markdown +++ b/source/_integrations/device_tracker.mqtt.markdown @@ -146,7 +146,7 @@ device: required: false type: string icon: - description: The icon for the device tracker. + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." required: false type: icon json_attributes_template: diff --git a/source/_integrations/fan.mqtt.markdown b/source/_integrations/fan.mqtt.markdown index 50eafc25bad..3650ba6dead 100644 --- a/source/_integrations/fan.mqtt.markdown +++ b/source/_integrations/fan.mqtt.markdown @@ -101,6 +101,10 @@ device: description: 'Identifier of a device that routes messages between this device and Home Assistant. Examples of such devices are hubs, or parent devices of a sub-device. This is used to show device topology in Home Assistant.' required: false type: string +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`. Usage example can be found in [MQTT sensor](/integrations/sensor.mqtt/#json-attributes-template-configuration) documentation." required: false diff --git a/source/_integrations/light.mqtt.markdown b/source/_integrations/light.mqtt.markdown index 549cd01e1d1..3db65515a60 100644 --- a/source/_integrations/light.mqtt.markdown +++ b/source/_integrations/light.mqtt.markdown @@ -181,6 +181,10 @@ hs_value_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the HS value." required: false type: string +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`. Usage example can be found in [MQTT sensor](/integrations/sensor.mqtt/#json-attributes-template-configuration) documentation." required: false @@ -532,6 +536,10 @@ hs: required: false type: boolean default: false +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`. Usage example can be found in [MQTT sensor](/integrations/sensor.mqtt/#json-attributes-template-configuration) documentation." required: false @@ -858,6 +866,10 @@ green_template: description: "[Template](/docs/configuration/templating/#processing-incoming-data) to extract green color from the state payload value." required: false type: string +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`. Usage example can be found in [MQTT sensor](/integrations/sensor.mqtt/#json-attributes-template-configuration) documentation." required: false diff --git a/source/_integrations/lock.mqtt.markdown b/source/_integrations/lock.mqtt.markdown index 1cb52e8d396..3dc3bfae24b 100644 --- a/source/_integrations/lock.mqtt.markdown +++ b/source/_integrations/lock.mqtt.markdown @@ -97,6 +97,10 @@ device: description: 'Identifier of a device that routes messages between this device and Home Assistant. Examples of such devices are hubs, or parent devices of a sub-device. This is used to show device topology in Home Assistant.' required: false type: string +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`. Usage example can be found in [MQTT sensor](/integrations/sensor.mqtt/#json-attributes-template-configuration) documentation." required: false diff --git a/source/_integrations/number.mqtt.markdown b/source/_integrations/number.mqtt.markdown index fa69e67300f..bf36dd2a23f 100644 --- a/source/_integrations/number.mqtt.markdown +++ b/source/_integrations/number.mqtt.markdown @@ -88,7 +88,7 @@ device: required: false type: string icon: - description: Icon for the number. + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." required: false type: icon json_attributes_template: diff --git a/source/_integrations/sensor.mqtt.markdown b/source/_integrations/sensor.mqtt.markdown index e082f81f8c0..b2eaeda5e75 100644 --- a/source/_integrations/sensor.mqtt.markdown +++ b/source/_integrations/sensor.mqtt.markdown @@ -103,7 +103,7 @@ force_update: type: boolean default: false icon: - description: The icon for the sensor. + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." required: false type: icon json_attributes_template: diff --git a/source/_integrations/switch.mqtt.markdown b/source/_integrations/switch.mqtt.markdown index 59f51b21c29..1447bc93eff 100644 --- a/source/_integrations/switch.mqtt.markdown +++ b/source/_integrations/switch.mqtt.markdown @@ -98,7 +98,7 @@ device: required: false type: string icon: - description: Icon for the switch. + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." required: false type: icon json_attributes_template: diff --git a/source/_integrations/vacuum.mqtt.markdown b/source/_integrations/vacuum.mqtt.markdown index 2bc77dff3be..4e7838ec4be 100644 --- a/source/_integrations/vacuum.mqtt.markdown +++ b/source/_integrations/vacuum.mqtt.markdown @@ -113,6 +113,10 @@ fan_speed_topic: description: The MQTT topic subscribed to receive fan speed values from the vacuum. required: false type: string +icon: + description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." + required: false + type: icon json_attributes_template: description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the JSON dictionary from messages received on the `json_attributes_topic`. Usage example can be found in [MQTT sensor](/integrations/sensor.mqtt/#json-attributes-template-configuration) documentation." required: false From 208bb247146cf3dbe2cb8eda3b61a8f946adc6dc Mon Sep 17 00:00:00 2001 From: Matthias Alphart Date: Tue, 30 Mar 2021 18:19:35 +0200 Subject: [PATCH 64/90] KNX passive addresses (#17071) Co-authored-by: Franck Nijhof --- source/_integrations/knx.markdown | 161 +++++++++++++++++------------- 1 file changed, 93 insertions(+), 68 deletions(-) diff --git a/source/_integrations/knx.markdown b/source/_integrations/knx.markdown index 3ec42d0378d..e4244026fac 100644 --- a/source/_integrations/knx.markdown +++ b/source/_integrations/knx.markdown @@ -58,13 +58,13 @@ There is currently support for the following device types within Home Assistant: ## Basic Configuration -To use your KNX bus in your installation, add the following lines to your `configuration.yaml` file: +To use your KNX devices from Home Assistant, add the following lines to your `configuration.yaml` file: ```yaml knx: ``` -In order to make use of the various platforms that KNX offers you will need to add the relevant configuration sections to your setup. This could either all be in the Home Assistant main `configuration.yaml` file, or in a separate YAML file that you include in the main file or even be split into multiple dedicated files as shown below: +In order to make use of the various platforms that KNX offers you will need to add the relevant configuration sections to your setup. This could either all be in the Home Assistant main `configuration.yaml` file, or in a separate YAML file that you include in the main file or even be split into multiple dedicated files. See [Splitting up the configuration](/docs/configuration/splitting_configuration/). ```yaml knx: @@ -107,6 +107,33 @@ state_updater: type: boolean {% endconfiguration %} +### Group addresses + +Group addresses are configured as strings or integers in the format "1/2/3" for 3-level GA-structure, "1/2" for 2-level GA-structure or "1" for free GA-structure. + +The HA KNX integration uses configured `state_address` or `*_state_address` to update the state of a function. These addresses are read by GroupValueRead requests on startup and when there was no incoming telegram for one hour (default `sync_state`). + +It is possible to configure passive/listening group addresses for all functions of every KNX platform (except `expose` and `notify`). This allows having multiple group addresses to update the state of its function (e.g., the brightness of a light). When group addresses are configured as a list of strings, the first item is the active sending or state-reading address and the rest is registered as passive addresses. This schema behaves like in ETS configuration where the first is the "sending" address and others are just for updating the communication object. + +If your KNX device provides active state communication objects it is advised to use `*_state_address` instead of passive addresses as it reduces configuration complexity and avoids wrong states (e.g., when channels are logically locked). + +```yaml +knx: + switch: + - name: "Switch without passive addresses" + address: "1/1/1" # this is the address that will be sent to + state_address: "8/8/8" # this is the address GroupValueRead requests are sent to + - name: "Switch with passive addresses" + address: + - "1/1/1" # this is the address that will be sent to + - "1/1/2" # this and following are passive addresses + - "1/1/3" + state_address: + - "8/8/8" # this is the address GroupValueRead requests are sent to + - "8/8/2" # this and following are passive addresses + - "8/8/3" +``` + ## Connection Under normal conditions no connection configuration should be needed. The integration will auto-detect KNX/IP interfaces and connect to one. This requires multicast communication to work in your environment. @@ -261,7 +288,7 @@ The `knx.event_register` service can be used to register (or unregister) group a address: description: Group address that shall be added or removed. required: true - type: string + type: [string, list] remove: description: If `True` the group address will be removed. required: false @@ -357,7 +384,7 @@ knx: state_address: description: KNX group address of the binary sensor. *DPT 1* required: true - type: string + type: [string, list] name: description: A name for this device used within Home Assistant. required: false @@ -563,7 +590,7 @@ name: temperature_address: description: KNX group address for reading current room temperature from KNX bus. *DPT 9.001* required: true - type: string + type: [string, list] temperature_step: description: Defines the step size in Kelvin for each step of setpoint_shift. required: false @@ -572,19 +599,19 @@ temperature_step: target_temperature_address: description: KNX group address for setting target temperature. *DPT 9.001* required: false - type: string + type: [string, list] target_temperature_state_address: description: KNX group address for reading current target temperature from KNX bus. *DPT 9.001* required: true - type: string + type: [string, list] setpoint_shift_address: description: KNX address for setpoint_shift. *DPT 6.010 or DPT 9.002 based on setpoint_shift_mode* required: false - type: string + type: [string, list] setpoint_shift_state_address: description: KNX address for reading setpoint_shift. *DPT 6.010 or DPT 9.002 based on setpoint_shift_mode* required: false - type: string + type: [string, list] setpoint_shift_mode: description: Defines the internal device DPT used. Either 'DPT6010' or 'DPT9002'. required: false @@ -603,51 +630,51 @@ setpoint_shift_max: operation_mode_address: description: KNX address for setting operation mode (Frost protection/night/comfort). *DPT 20.102* required: false - type: string + type: [string, list] operation_mode_state_address: description: KNX address for reading operation mode. *DPT 20.102* required: false - type: string + type: [string, list] controller_status_address: description: KNX address for HVAC controller status (in accordance with KNX AN 097/07 rev 3). required: false - type: string + type: [string, list] controller_status_state_address: description: KNX address for reading HVAC controller status. required: false - type: string + type: [string, list] controller_mode_address: description: KNX address for setting HVAC controller modes. *DPT 20.105* required: false - type: string + type: [string, list] controller_mode_state_address: description: KNX address for reading HVAC control mode. *DPT 20.105* required: false - type: string + type: [string, list] heat_cool_address: description: KNX address for switching between heat/cool mode. *DPT 1.100* required: false - type: string + type: [string, list] heat_cool_state_address: description: KNX address for reading heat/cool mode. *DPT 1.100* required: false - type: string + type: [string, list] operation_mode_frost_protection_address: description: KNX address for switching on/off frost/heat protection mode. *DPT 1* required: false - type: string + type: [string, list] operation_mode_night_address: description: KNX address for switching on/off night mode. *DPT 1* required: false - type: string + type: [string, list] operation_mode_comfort_address: description: KNX address for switching on/off comfort mode. *DPT 1* required: false - type: string + type: [string, list] operation_mode_standby_address: description: KNX address for switching on/off standby mode. *DPT 1* required: false - type: string + type: [string, list] operation_modes: description: Overrides the supported operation modes. Provide the supported `preset_mode` values for your device. required: false @@ -659,7 +686,7 @@ controller_modes: on_off_address: description: KNX address for switching the climate device on/off. *DPT 1* required: false - type: string + type: [string, list] on_off_invert: description: Value for switching the climate device on/off is inverted. required: false @@ -668,7 +695,7 @@ on_off_invert: on_off_state_address: description: KNX address for gathering the current state (on/off) of the climate device. *DPT 1* required: false - type: string + type: [string, list] min_temp: description: Override the minimum temperature. required: false @@ -713,31 +740,31 @@ name: move_long_address: description: KNX group address for moving the cover full up or down. *DPT 1* required: false - type: string + type: [string, list] move_short_address: description: KNX group address for moving the cover short time up or down. Used by some covers also as the means to stop the cover, if no dedicated `stop_address` exists on the actuator. *DPT 1* required: false - type: string + type: [string, list] stop_address: description: KNX group address for stopping the current movement from the cover. *DPT 1* required: false - type: string + type: [string, list] position_address: description: KNX group address for moving the cover to the dedicated position. *DPT 5.001* required: false - type: string + type: [string, list] position_state_address: description: Separate KNX group address for requesting the current position of the cover. *DPT 5.001* required: false - type: string + type: [string, list] angle_address: description: KNX group address for moving the cover to the dedicated angle. *DPT 5.001* required: false - type: string + type: [string, list] angle_state_address: description: Separate KNX group address for requesting the current angle of cover. *DPT 5.001* required: false - type: string + type: [string, list] travelling_time_down: description: Time cover needs to travel down in seconds. Needed to calculate the intermediate positions of cover while traveling. required: false @@ -790,19 +817,19 @@ name: address: description: KNX group address for setting the percentage or step of the fan. *DPT 5.001* or *DPT 5.010* required: true - type: string + type: [string, list] state_address: description: KNX group address for retrieving the percentage or step of the fan. *DPT 5.001* or *DPT 5.010* required: false - type: string + type: [string, list] oscillation_address: description: KNX group address for switching the fan oscillation on or off. *DPT 1* required: false - type: string + type: [string, list] oscillation_state_address: description: KNX group address for retrieving the state of the fan oscillation. *DPT 1* required: false - type: string + type: [string, list] max_step: description: The maximum amount of steps for a step-controlled fan. If set, the integration will convert percentages to steps automatically. required: false @@ -832,11 +859,11 @@ knx: address: description: KNX group address for switching the light on and off. *DPT 1.001* required: true - type: string + type: [string, list] state_address: description: KNX group address for retrieving the switch state of the light. *DPT 1.001* required: false - type: string + type: [string, list] name: description: A name for this device used within Home Assistant. required: false @@ -844,27 +871,27 @@ name: brightness_address: description: KNX group address for setting the brightness of the light in percent (absolute dimming). *DPT 5.001* required: false - type: string + type: [string, list] brightness_state_address: description: KNX group address for retrieving the brightness of the light in percent. *DPT 5.001* required: false - type: string + type: [string, list] color_address: description: KNX group address for setting the RGB color of the light. *DPT 232.600* required: false - type: string + type: [string, list] color_state_address: description: KNX group address for retrieving the RGB color of the light. *DPT 232.600* required: false - type: string + type: [string, list] rgbw_address: description: KNX group address for setting the RGBW color of the light. *DPT 251.600* required: false - type: string + type: [string, list] rgbw_state_address: description: KNX group address for retrieving the RGBW color of the light. *DPT 251.600* required: false - type: string + type: [string, list] individual_colors: description: Used when the actuator only supports individual group addresses for colors. When `address` is specified for all 3 (or 4) individual colors the root `address` key can be omitted. required: false @@ -877,21 +904,19 @@ individual_colors: keys: address: description: KNX group address to switch the red component. *DPT 1.001* - type: string + type: [string, list] required: false state_address: description: KNX group address for the state of the red component. *DPT 1.001* - type: string + type: [string, list] required: false brightness_address: description: KNX group address to set the brightness of the red component. *DPT 5.001* - type: string + type: [string, list] required: true brightness_state_address: description: KNX group address for the current brightness of the red component. *DPT 5.001* - type: string - required: false - type: string + type: [string, list] required: false green: description: Group addresses for the green component. Same keys available as for red component above. @@ -908,11 +933,11 @@ individual_colors: color_temperature_address: description: KNX group address for setting the color temperature of the light. *DPT 5.001 or 7.600 based on color_temperature_mode* required: false - type: string + type: [string, list] color_temperature_state_address: description: KNX group address for retrieving the color temperature of the light. *DPT 5.001 or 7.600 based on color_temperature_mode* required: false - type: string + type: [string, list] color_temperature_mode: description: Color temperature group address data type. `absolute` color temperature in Kelvin. *color_temperature_address -> DPT 7.600*. `relative` color temperature in percent cold white (0% warmest; 100% coldest). *color_temperature_address -> DPT 5.001* required: false @@ -990,7 +1015,7 @@ knx: address: description: KNX group address of the notification. *DPT 16.000* required: true - type: string + type: [string, list] name: description: A name for this device used within Home Assistant. required: false @@ -1014,7 +1039,7 @@ knx: address: description: KNX group address for the scene. *DPT 17.001* required: true - type: string + type: [string, list] scene_number: description: KNX scene number to be activated (range 1..64 ). required: true @@ -1056,7 +1081,7 @@ knx: state_address: description: KNX group address of the sensor. required: true - type: string + type: [string, list] type: description: A type from the value types table below must be defined. The DPT of the group address should match the expected KNX DPT to be parsed correctly. required: true @@ -1262,7 +1287,7 @@ knx: address: description: KNX group address for switching the switch on/off. *DPT 1* required: true - type: string + type: [string, list] name: description: A name for this device used within Home Assistant. required: false @@ -1271,7 +1296,7 @@ name: state_address: description: Separate KNX group address for retrieving the switch state. *DPT 1* required: false - type: string + type: [string, list] invert: description: Invert the telegrams payload before processing or sending. required: false @@ -1318,55 +1343,55 @@ name: address_temperature: description: KNX group address for reading current outside temperature from KNX bus. *DPT 9.001* required: true - type: string + type: [string, list] address_brightness_south: description: KNX group address for reading current brightness to south coordinate from KNX bus. *DPT 9.004* required: false - type: string + type: [string, list] address_brightness_west: description: KNX group address for reading current brightness to west coordinate from KNX bus. *DPT 9.004* required: false - type: string + type: [string, list] address_brightness_east: description: KNX group address for reading current brightness to east coordinate from KNX bus. *DPT 9.004* required: false - type: string + type: [string, list] address_brightness_north: description: KNX group address for reading current brightness to north coordinate from KNX bus. *DPT 9.004* required: false - type: string + type: [string, list] address_wind_bearing: description: KNX group address for reading current wind bearing from KNX bus. *DPT 5.003* required: false - type: string + type: [string, list] address_wind_speed: description: KNX group address for reading current wind speed from KNX bus. *DPT 9.005* required: false - type: string + type: [string, list] address_rain_alarm: description: KNX group address for reading if rain alarm is on/off. required: false - type: string + type: [string, list] address_frost_alarm: description: KNX group address for reading if frost alarm is on/off. required: false - type: string + type: [string, list] address_wind_alarm: description: KNX group address for reading if wind alarm is on/off. required: false - type: string + type: [string, list] address_day_night: description: KNX group address for reading if it's day/night. required: false - type: string + type: [string, list] address_air_pressure: description: KNX address reading current air pressure. *DPT 9.006* required: false - type: string + type: [string, list] address_humidity: description: KNX address for reading current humidity. *DPT 9.007* required: false - type: string + type: [string, list] create_sensors: description: If true, dedicated sensor entities are created for all configured properties. required: false From 9d792b032d3b0a675ae7f1224b7af6d49361d3de Mon Sep 17 00:00:00 2001 From: Jacob Shufro <116244+jshufro@users.noreply.github.com> Date: Tue, 30 Mar 2021 12:53:18 -0400 Subject: [PATCH 65/90] Add documentation for logger regex filters (#17160) * Add documentation for logger regex filters * Tweak Co-authored-by: Franck Nijhof --- source/_integrations/logger.markdown | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/source/_integrations/logger.markdown b/source/_integrations/logger.markdown index e61bca4380a..e01a2f98dbf 100644 --- a/source/_integrations/logger.markdown +++ b/source/_integrations/logger.markdown @@ -88,6 +88,14 @@ where **namespace** is the ** currently logging. '<component_namespace>': description: Logger namespace of the component. See [log_level](#log-levels). type: string + filters: + description: Regular Expression logging filters. + required: false + type: map + keys: + '<component_namespace>': + description: Logger namespace of the component and a list of Regular Expressions. See [Log Filters](#log-filters). + type: list {% endconfiguration %} In the example, do note the difference between 'glances_api' and 'homeassistant.components.glances' namespaces, @@ -110,6 +118,26 @@ Possible log severity levels, listed in order from most severe to least severe, - debug - notset +### Log Filters + +Service-specific Regular Expression filters for logs. A message is omitted if it matches the Regular Expression. + +An example configuration might look like this: + +```yaml +# Example configuration.yaml entry +logger: + default: info + logs: + custom_components.my_integration: critical + filters: + custom_component.my_integartion: + - "HTTP 429" # Filter all HTTP 429 errors + - "Request to .*unreliable.com.* Timed Out" + homeassistant.components.nws: + - "^Error handling request$" +``` + ## Services ### Service `set_default_level` From 6a35fa5380fc116b00599d92b9abb0c92e45f5d5 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 30 Mar 2021 10:13:29 -0700 Subject: [PATCH 66/90] Document trigger entity (#17092) Co-authored-by: Hmmbob <33529490+hmmbob@users.noreply.github.com> Co-authored-by: Franck Nijhof --- source/_docs/automation/templating.markdown | 20 +----- source/_docs/automation/trigger.markdown | 17 ++++- source/_integrations/template.markdown | 74 ++++++++++++++++++++- 3 files changed, 87 insertions(+), 24 deletions(-) diff --git a/source/_docs/automation/templating.markdown b/source/_docs/automation/templating.markdown index 38da81fa0bf..937aa423b91 100644 --- a/source/_docs/automation/templating.markdown +++ b/source/_docs/automation/templating.markdown @@ -1,26 +1,10 @@ --- -title: "Automation Templating" -description: "Advanced automation documentation using templating." +title: "Automation Trigger Variables" +description: "List all available variables made available by triggers." --- Automations support [templating](/docs/configuration/templating/) in the same way as scripts do. In addition to the [Home Assistant template extensions](/docs/configuration/templating/#home-assistant-template-extensions) available to scripts, the `trigger` template variable is available. -
    - - Be aware that if you reference a `trigger` state object in templates of an automation' `action` or `condition` sections, attempting to test that automation by calling the `automation.trigger` service or by clicking EXECUTE in the More Info box for the automation will not work. This is because the trigger state object doesn't exist in those contexts. One way to test automations like these is to manually check that the templates work as expected by pasting them in {% my developer_template title="Developer Tools > Template" %} together with your trigger's definition like: - -{%raw%} - -```yaml -{% set trigger={'to_state':{'state': 'heat'}} %} -{% set option = trigger.to_state.state %} -{{ 'on' if option == 'heat' else 'off' }} -``` - -{%endraw%} - -
    - ## Available Trigger Data The following tables show the available trigger data per platform. diff --git a/source/_docs/automation/trigger.markdown b/source/_docs/automation/trigger.markdown index aca3c69e3c6..bb29ef57a97 100644 --- a/source/_docs/automation/trigger.markdown +++ b/source/_docs/automation/trigger.markdown @@ -3,13 +3,24 @@ title: "Automation Trigger" description: "All the different ways how automations can be triggered." --- -## What are triggers - Triggers are what starts the processing of an automation rule. When _any_ of the automation's triggers becomes true (trigger _fires_), Home Assistant will validate the [conditions](/docs/automation/condition/), if any, and call the [action](/docs/automation/action/). An automation can be triggered by an event, with a certain entity state, at a given time, and more. These can be specified directly or more flexible via templates. It is also possible to specify multiple triggers for one automation. -The following sections introduce all trigger types and further details to get started. +- [Event trigger](#event-trigger) +- [Home Assistant trigger](#home-assistant-trigger) +- [MQTT trigger](#mqtt-trigger) +- [Numeric state trigger](#numeric-state-trigger) +- [State trigger](#state-trigger) +- [Sun trigger](#sun-trigger) +- [Tag trigger](#tag-trigger) +- [Template trigger](#template-trigger) +- [Time trigger](#time-trigger) +- [Time pattern trigger](#time-pattern-trigger) +- [Webhook trigger](#webhook-trigger) +- [Zone trigger](#zone-trigger) +- [Geolocation trigger](#geolocation-trigger) +- [Device triggers](#device-triggers) ## Trigger variables diff --git a/source/_integrations/template.markdown b/source/_integrations/template.markdown index 62337f62370..369304943da 100644 --- a/source/_integrations/template.markdown +++ b/source/_integrations/template.markdown @@ -23,7 +23,22 @@ ha_platforms: - weather --- -The `template` platform supports sensors which get their values from other entities. +The `template` integration allows creating entities which derive their values from other entities. This is done by defining [templates](/docs/configuration/templating/) for each property of an entity, like the name or the state. Entities are updated automatically whenever a value that a template relies on changes. + +For sensors it's also possible to derive the state from [automation triggers](#configuration-for-trigger-based-template-sensors). + +Available template platforms: + +- [Alarm_control_panel](/integrations/alarm_control_panel.template/) +- [Binary_sensor](/integrations/binary_sensor.template/) +- [Cover](/integrations/cover.template/) +- [Fan](/integrations/fan.template/) +- [Light](/integrations/light.template/) +- [Lock](/integrations/lock.template/) +- Sensor (this page) +- [Switch](/integrations/switch.template/) +- [Vacuum](/integrations/vacuum.template/) +- [Weather](/integrations/weather.template/) ## Configuration @@ -49,7 +64,7 @@ sensor: {% configuration %} sensors: - description: List of your sensors. + description: Map of your sensors. required: true type: map keys: @@ -90,7 +105,7 @@ sensor: "attribute: template": description: The attribute and corresponding template. required: true - type: template + type: template availability_template: description: Defines a template to get the `available` state of the component. If the template returns `true`, the device is `available`. If the template returns any other value, the device will be `unavailable`. If `availability_template` is not configured, the component will always be `available`. required: false @@ -103,6 +118,59 @@ sensor: default: None {% endconfiguration %} +## Configuration for trigger-based template sensors + +Trigger-based template sensors allow the user to define [an automation trigger][trigger-doc] for a group of template sensors. Whenever the trigger fires, the template sensor will re-render and it will have access to [the trigger data](/docs/automation/templating/) in the templates. This feature is a great way to create data based on webhook data, or have sensors be updated based on a time-schedule. + +Trigger-based template entities are defined in YAML directly under the `template:` key. You can define multiple configuration blocks as a list. Each block defines one or more triggers and the sensors that should be updated when the trigger fires. + +Trigger-based entities do not automatically update when states referenced in the templates change. This functionality can be added by defining a [state trigger](/docs/automation/trigger/#state-trigger) for each entity that you want to trigger updates. + +{% raw %} + +```yaml +# Example configuration entry +template: + - trigger: + - platform: webhook + webhook_id: my-super-secret-webhook-id + sensor: + - name: "Webhook Temperature" + state: "{{ trigger.json.temperature }}" + - name: "Webhook Humidity" + state: "{{ trigger.json.humidity }}" +``` + +{% endraw %} + +You can test this trigger entity with the following CURL command: + +```bash +curl --header "Content-Type: application/json" \ + --request POST \ + --data '{"temperature": 5, "humidity": 34}' \ + http://homeassistant.local:8123/api/webhook/my-super-secret-webhook-id +``` + +{% configuration %} +trigger: + description: The trigger configuration for this entity. [See trigger documentation](/docs/automation/trigger) + required: true + type: list +unique_id: + description: The unique ID for this trigger. This will be prefixed to all unique IDs of all entities in this block. + required: false + type: string +sensor: + description: Map of your sensors to create from the trigger data. For available keys, see [configuration variables](#configuration-variables) above. + required: true + type: map +{% endconfiguration %} + +

    It's currently only possible to define trigger-based entities via the top-level configuration. These entities are not yet included when reloading template entities.

    + +[trigger-doc]: /docs/automation/trigger + ## Considerations ### Startup From 3b38e3ae83eef96df654bb81f949cee9a82de9ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 30 Mar 2021 22:22:17 +0200 Subject: [PATCH 67/90] Remove analytics from updater (#17189) Co-authored-by: Franck Nijhof --- source/_docs/backend/updater.markdown | 52 -------------------- source/_includes/asides/docs_navigation.html | 1 - source/_integrations/default_config.markdown | 1 + source/_integrations/updater.markdown | 34 ------------- source/_redirects | 1 + 5 files changed, 2 insertions(+), 87 deletions(-) delete mode 100644 source/_docs/backend/updater.markdown diff --git a/source/_docs/backend/updater.markdown b/source/_docs/backend/updater.markdown deleted file mode 100644 index e041a0e372d..00000000000 --- a/source/_docs/backend/updater.markdown +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Updater" -description: "Details what the updater integration is reporting about your Home Assistant instance." ---- - -Starting with 0.31 the [updater component](/integrations/updater/) sends an optional report about Home Assistant instance. - -If you want to opt-in to include integration information, add `include_used_components` to your configuration. This will allow the Home Assistant developers to focus development efforts on the most popular components. - -```yaml -updater: - include_used_components: true -``` - -We are only collecting this information to better understand our user base to provide better long term support and feature development. - -| Name | Description | Example | Data Source | -| --------------------- | ------------------------------------------ | ---------------------------------- | -------------- | -| `arch` | CPU Architecture | `x86_64` | Local Instance | -| `distribution` | Linux Distribution name (only Linux) | `Ubuntu` | Local Instance | -| `docker` | True if running inside Docker | `false` | Local Instance | -| `first_seen_datetime` | First time instance ID was submitted | `2016-10-22T19:56:03.542Z` | Update Server | -| `geo_city` | GeoIP determined city | `Oakland` | Update Server | -| `geo_country_code` | GeoIP determined country code | `US` | Update Server | -| `geo_country_name` | GeoIP determined country name | `United States` | Update Server | -| `geo_latitude` | GeoIP determined latitude | `37.8047` | Update Server | -| `geo_longitude` | GeoIP determined longitude | `-122.2124` | Update Server | -| `geo_metro_code` | GeoIP determined metro code | `807` | Update Server | -| `geo_region_code` | GeoIP determined region code | `CA` | Update Server | -| `geo_region_name` | GeoIP determined region name | `California` | Update Server | -| `geo_time_zone` | GeoIP determined time zone | `America/Los_Angeles` | Update Server | -| `geo_zip_code` | GeoIP determined zip code | `94602` | Update Server | -| `last_seen_datetime` | Most recent time instance ID was submitted | `2016-10-22T19:56:03.542Z` | Update Server | -| `os_name` | Operating system name | `Darwin` | Local Instance | -| `os_version` | Operating system version | `10.12` | Local Instance | -| `python_version` | Python version | `3.5.2` | Local Instance | -| `timezone` | Timezone | `America/Los_Angeles` | Local Instance | -| `user_agent` | User agent used to submit analytics | `python-requests/2.11.1` | Local Instance | -| `uuid` | Unique identifier | `10321ee6094d4a2ebb5ed55c675d5f5e` | Local Instance | -| `version` | Home Assistant version | `0.31.0` | Local Instance | -| `virtualenv` | True if running inside virtualenv | `true` | Local Instance | - -In addition to the above collected data, the server will also use your IP address to do a geographic IP address lookup to determine a general geographic area that your address is located in. To be extremely, extremely clear about this bit: __The Home Assistant updater does not: store your IP address in a database and also does not submit the location information from your `configuration.yaml`.__ - -Our tests showed that at best, we get 4 digits of accuracy on your IP address location which is a 5 mile radius of your actual IP location, assuming that it is even correct in the first place (geo IP lookups are very hit or miss). - -The server also adds two timestamps to the data: - -- the original date your instance UUID was first seen -- the timestamp of the last time we have seen your instance - -We will never publicly expose individual gathered data. We might however publish aggregated stats about our user base (example: 70% of all users use Linux). We will never sell or allow the use of this information for non-Home Assistant development purposes. diff --git a/source/_includes/asides/docs_navigation.html b/source/_includes/asides/docs_navigation.html index a7546728ac3..91094ac2281 100644 --- a/source/_includes/asides/docs_navigation.html +++ b/source/_includes/asides/docs_navigation.html @@ -122,7 +122,6 @@ {% active_link /docs/backend/ Backend %}
    • {% active_link /docs/backend/database/ Database %}
    • -
    • {% active_link /docs/backend/updater/ Updater %}
  • diff --git a/source/_integrations/default_config.markdown b/source/_integrations/default_config.markdown index 17214f4e08c..8c6fdd7e8d5 100644 --- a/source/_integrations/default_config.markdown +++ b/source/_integrations/default_config.markdown @@ -10,6 +10,7 @@ ha_iot_class: Calculated This integration is a meta-component and configures a default set of integrations for Home Assistant to load. The integrations that will be loaded are: +- [Analytics](/integrations/analytics) (`analytics`) - [Automation](/integrations/automation/) (`automation`) - [Home Assistant Cloud](/integrations/cloud/) (`cloud`) - [Configuration](/integrations/config/) (`config`) diff --git a/source/_integrations/updater.markdown b/source/_integrations/updater.markdown index c47c3af735e..93c70067736 100644 --- a/source/_integrations/updater.markdown +++ b/source/_integrations/updater.markdown @@ -15,8 +15,6 @@ ha_platforms: The `updater` binary sensor will check daily for new releases. The state will be "on" when an update is available. Otherwise, the state will be "off". The newer version, as well as the link to the release notes, are attributes of the updater. -The updater integration will also collect basic information about the running Home Assistant instance and its environment. The information includes the current Home Assistant version, the time zone, Python version and operating system information. No identifiable information (i.e., IP address, GPS coordinates, etc.) will ever be collected. If you are concerned about your privacy, you are welcome to scrutinize the Python [source code](https://github.com/home-assistant/home-assistant/tree/dev/homeassistant/components/updater). - ## Configuration This integration is by default enabled, unless you've disabled or removed the [`default_config:`](/integrations/default_config/) line from your configuration. If that is the case, the following example shows you how to enable this integration manually: @@ -25,38 +23,6 @@ This integration is by default enabled, unless you've disabled or removed the [` updater: ``` -{% configuration %} -reporting: - description: Whether or not to share system information when checking for updates. - required: false - type: boolean - default: true -include_used_components: - description: Whether or not to report the integrations that you are using in Home Assistant. - required: false - type: boolean - default: false -{% endconfiguration %} - -For further information about the Updater's data, please check the [detailed overview](/docs/backend/updater/). If you choose not to share any information when checking for updates, you can set `reporting: false`. - -It is possible to report the integrations that you are using to the Home Assistant developers. This will help them focus on improving the popular ones. To enable this option, you have to add `include_used_components: true`. - -```json -"components": [ - "apcupsd", - "api", - "automation", - "binary_sensor", - "binary_sensor.zwave", - "camera", - "camera.uvc", - "config", - "config.core", - ... -] -``` - ## Notification For an added bonus, an automation integration can be created to send a message with a notifier when that state of this component's entity changes. diff --git a/source/_redirects b/source/_redirects index 4ad849a4135..30ee4f54810 100644 --- a/source/_redirects +++ b/source/_redirects @@ -2020,6 +2020,7 @@ # Moved documentation /details/database /docs/backend/database /details/updater /docs/backend/updater +/docs/backend/updater /integrations/analytics /docs/ecosystem/ios/ https://companion.home-assistant.io/ /docs/ecosystem/ios/devices_file https://companion.home-assistant.io/ /docs/ecosystem/ios/integration https://companion.home-assistant.io/docs/integrations/integrations From 17072f3ee4d4515342861a6ac3a05306c78ba936 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 30 Mar 2021 16:51:07 -0400 Subject: [PATCH 68/90] Update zwave_js docs to reflect changes in Z-Wave JS 7.0.0 (#17053) * Update docs to reflect changes in Z-Wave JS 7.0.0 and to add the new notification event type * grammar * grammar * fix event names * grammar * remove type from value notification event * Update source/_integrations/zwave_js.markdown Co-authored-by: Martin Hjelmare Co-authored-by: Martin Hjelmare --- source/_integrations/zwave_js.markdown | 37 +++++++++++++++++++++----- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/source/_integrations/zwave_js.markdown b/source/_integrations/zwave_js.markdown index b68ec215ca6..c8dc34c3aeb 100644 --- a/source/_integrations/zwave_js.markdown +++ b/source/_integrations/zwave_js.markdown @@ -214,33 +214,58 @@ Valid code slots are between 1-254. ## Events -Events are fired when you press a button on a remote (aka Central Scene support) or when a stateless value is being signalled by a device. You can test what events come in using the event {% my developer_events title="developer tools in Home Assistant" %} and subscribe to `zwave_js_event`. Once you know what the event data looks like, you can use this to create automations. +There are two types of events that are fired, notification events and value notification events. You can test what events come in using the event {% my developer_events title="developer tools in Home Assistant" %} and subscribing to the `zwave_js_notification` or `zwave_js_value_notification` events respectively. Once you know what the event data looks like, you can use this to create automations. ### Node events (Notification) -These are events fired by the device using the notification command class. The `parameters` attribute in the example below is optional, and when it is included, the keys in the attribute will vary depending on the event. +Check the [Z-Wave JS notification event documentation](https://zwave-js.github.io/node-zwave-js/#/api/node?id=quotnotificationquot) for an explanation of the notification event data. These events fire with the `zwave_js_notification` event type. + +#### Notification Command Class + +These are notification events fired by devices using the Notification command class. The `parameters` attribute in the example below is optional, and when it is included, the keys in the attribute will vary depending on the event. ```json { - "type": "notification", "domain": "zwave_js", "node_id": 1, "home_id": "974823419", "device_id": "ad8098fe80980974", - "label": "Keypad lock operation", + "command_class": 113, + "command_class_name": "Notification", + "type": 6, + "event": 5, + "label": "Access Control", + "event_label": "Keypad lock operation", "parameters": {"userId": 1} } ``` +#### Entry Control Command Class + +These are notification events fired by devices using the Entry Control command class. + +```json +{ + "domain": "zwave_js", + "node_id": 1, + "home_id": "974823419", + "device_id": "ad8098fe80980974", + "command_class": 111, + "command_class_name": "Entry Control", + "event_type": 6, + "data_type": 5, + "event_data": "555" +} +``` + ## Scene events (Value Notification) -Value Notifications are used for stateless values, like `Central Scenes` and `Scene Activation`. +Value Notifications are used for stateless values, like `Central Scenes` and `Scene Activation`. These events fire with the `zwave_js_value_notification` event type. Value Notification example: ```json { - "type": "value_notification", "domain": "zwave_js", "node_id": 1, "home_id": "974823419", From b6db2602dbddcc015b9725c723d8a4b526cb8cb5 Mon Sep 17 00:00:00 2001 From: Martin Hjelmare Date: Wed, 31 Mar 2021 11:20:46 +0200 Subject: [PATCH 69/90] Remove zwave js GUI node configuration limitation (#17203) --- source/_integrations/zwave_js.markdown | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/_integrations/zwave_js.markdown b/source/_integrations/zwave_js.markdown index c8dc34c3aeb..f3bf97fc9b1 100644 --- a/source/_integrations/zwave_js.markdown +++ b/source/_integrations/zwave_js.markdown @@ -31,7 +31,7 @@ ha_platforms: This integration allows you to control a Z-Wave network via the [Z-Wave JS](https://zwave-js.github.io/node-zwave-js/#/) driver. This is our recommended Z-Wave integration for Home Assistant. -Please review the limitations [below](/integrations/zwave_js/#current-limitations) before you get started as a few devices still may not work or only work partially. +Please review the limitations [below](/integrations/zwave_js/#current-limitations) before you get started as a few devices still may not work or only work partially. ## Quick start (Home Assistant including Supervisor) @@ -100,7 +100,7 @@ Example 3: ```yaml service: zwave_js.set_config_parameter target: - entity_id: switch.fan + entity_id: switch.fan data: entity_id: switch.fan parameter: "LED 1 Blink Status (bottom)" @@ -120,7 +120,7 @@ This service will bulk set multiple partial configuration parameters. Be warned #### Examples of bulk setting partial parameter values -Let's use parameter 21 for [this device](https://devices.zwave-js.io/?jumpTo=0x031e:0x000a:0x0001:0.0) as an example to show how partial parameters can be bulk set. In this case, we want to set `0xff` to `127`, `0x7f00` to `10`, and `0x8000` to `1` (or the raw value of `4735`). +Let's use parameter 21 for [this device](https://devices.zwave-js.io/?jumpTo=0x031e:0x000a:0x0001:0.0) as an example to show how partial parameters can be bulk set. In this case, we want to set `0xff` to `127`, `0x7f00` to `10`, and `0x8000` to `1` (or the raw value of `4735`).
    @@ -288,7 +288,6 @@ Value Notification example: As this integration is still in the early stages there are some important limitations to be aware of. - While support for the most common devices is working, some command classes are not yet (fully) implemented in Z-Wave JS. You can track the status [here](https://github.com/zwave-js/node-zwave-js/issues/6). -- Configuration of Z-Wave nodes within the Home Assistant UI is not yet implemented, but a [service](#service-zwave_js.set_config_parameter) is available with limited configuration capabilities. If the service doesn't meet your needs, you will need to use another tool, such as [zwavejs2mqtt](https://github.com/zwave-js/zwavejs2mqtt), to manage device configuration. - There currently is no migration path available from any of the other Z-Wave implementations in Home Assistant. Your Z-Wave network is however stored on your stick so migrating will only require you to redo your device and entity naming. You can keep track of the Roadmap for the Z-Wave JS integration [here](https://github.com/home-assistant-libs/zwave-js-server-python/issues/56). From f7666ada93b812609b8331a71f20d199bce97e96 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 31 Mar 2021 11:29:57 +0200 Subject: [PATCH 70/90] Add color_mode support to MQTT JSON light (#17205) --- source/_integrations/light.mqtt.markdown | 51 +++++++++++------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/source/_integrations/light.mqtt.markdown b/source/_integrations/light.mqtt.markdown index 3db65515a60..54cbad670df 100644 --- a/source/_integrations/light.mqtt.markdown +++ b/source/_integrations/light.mqtt.markdown @@ -15,6 +15,7 @@ The `mqtt` light platform lets you control your MQTT enabled lights through one | Function | [`default`](#default-schema) | [`json`](#json-schema) | [`template`](#template-schema) | |-------------------|------------------------------------------------------------|----------------------------------------------------------------------|------------------------------------------------------------------------------| | Brightness | ✔ | ✔ | ✔ | +| Color mode | | ✔ | | | Color temperature | ✔ | ✔ | ✔ | | Effects | ✔ | ✔ | ✔ | | Flashing | ✘ | ✔ | ✔ | @@ -397,16 +398,19 @@ light: The `mqtt` light platform with JSON schema lets you control a MQTT-enabled light that can receive [JSON](https://en.wikipedia.org/wiki/JSON) messages. -This schema supports on/off, brightness, RGB colors, XY colors, color temperature, transitions, short/long flashing and white values. The messages sent to/from the lights look similar to this, omitting fields when they aren't needed: +This schema supports on/off, brightness, RGB colors, XY colors, color temperature, transitions, short/long flashing and white values. The messages sent to/from the lights look similar to this, omitting fields when they aren't needed. The `color_mode` will not be present in messages sent to the light. It is optional in messages received from the light, but can be used to disambiguate the current mode in the light. In the example below, `color_mode` is set to `rgb` and `color_temp`, `color.c`, `color.w`, color.x`, `color.y`, `color.h`, `color.s` will all be ignored: ```json { "brightness": 255, + "color_mode": "rgb", "color_temp": 155, "color": { "r": 255, "g": 180, "b": 200, + "c": 100, + "w": 50, "x": 0.406, "y": 0.301, "h": 344.0, @@ -474,8 +478,8 @@ brightness_scale: required: false type: integer default: 255 -color_temp: - description: Flag that defines if the light supports color temperature. +color_mode: + description: Flag that defines if the light supports color modes. required: false type: boolean default: false @@ -531,11 +535,6 @@ flash_time_short: required: false type: integer default: 2 -hs: - description: Flag that defines if the light supports HS colors. - required: false - type: boolean - default: false icon: description: "[Icon](/docs/configuration/customizing-devices/#icon) for the entity." required: false @@ -586,11 +585,6 @@ retain: required: false type: boolean default: false -rgb: - description: Flag that defines if the light supports RGB colors. - required: false - type: boolean - default: false schema: description: The schema to use. Must be `json` to select the JSON schema". required: false @@ -600,20 +594,14 @@ state_topic: description: The MQTT topic subscribed to receive state updates. required: false type: string +supported_color_modes: + description: A list of color modes supported by the list. This is required if `color_mode` is `True`. Possible color modes are `onoff`, `brightness`, `color_temp`, `hs`, `xy`, `rgb`, `rgbw`, `rgbww`. + required: false + type: list unique_id: description: An ID that uniquely identifies this light. If two lights have the same unique ID, Home Assistant will raise an exception. required: false type: string -white_value: - description: Flag that defines if the light supports white values. - required: false - type: boolean - default: false -xy: - description: Flag that defines if the light supports XY colors. - required: false - type: boolean - default: false {% endconfiguration %}
    @@ -645,7 +633,8 @@ light: state_topic: "home/rgb1" command_topic: "home/rgb1/set" brightness: true - rgb: true + color_mode: true + supported_color_modes: ["rgb"] ``` ### Brightness and no RGB support @@ -661,6 +650,8 @@ light: state_topic: "home/rgb1" command_topic: "home/rgb1/set" brightness: true + color_mode: true + supported_color_modes: ["brightness"] ``` ### Brightness Scaled @@ -676,6 +667,8 @@ light: command_topic: "home/light/set" brightness: true brightness_scale: 4095 + color_mode: true + supported_color_modes: ["brightness"] ``` Home Assistant will then convert its 8bit value in the message to and from the device: @@ -689,7 +682,7 @@ Home Assistant will then convert its 8bit value in the message to and from the d ### HS Color -To use a light with hue+saturation as the color model, set `hs` to `true` in the platform configuration: +To use a light with hue+saturation as the color model, set `supported_color_modes` to `["hs"]` in the platform configuration: ```yaml light: @@ -698,7 +691,8 @@ light: name: mqtt_json_hs_light state_topic: "home/light" command_topic: "home/light/set" - hs: true + color_mode: true + supported_color_modes: ["hs"] ``` Home Assistant expects the hue values to be in the range 0 to 360 and the saturation values to be scaled from 0 to 100. For example, the following is a blue color shade: @@ -706,6 +700,7 @@ Home Assistant expects the hue values to be in the range 0 to 360 and the satura ```json { "state": "ON", + "color_mode": "hs", "color": { "h": 24.0, "s": 100.0 @@ -726,8 +721,8 @@ light: state_topic: "home/rgbw1" command_topic: "home/rgbw1/set" brightness: true - rgb: true - white_value: true + color_mode: true + supported_color_modes: ["rgbw"] ``` From 7ec532bffb7671cb99e28356a54d18db5ae46aab Mon Sep 17 00:00:00 2001 From: Nicolas Braem Date: Wed, 31 Mar 2021 12:36:52 +0200 Subject: [PATCH 71/90] add vicare fuelcell heating_type (#16920) --- source/_integrations/vicare.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_integrations/vicare.markdown b/source/_integrations/vicare.markdown index 4a1f5031e51..2173c099475 100644 --- a/source/_integrations/vicare.markdown +++ b/source/_integrations/vicare.markdown @@ -52,7 +52,7 @@ circuit: required: false type: integer heating_type: - description: One of `generic`, `gas` or `heatpump`. Specifying the heating_type provides additional attributes and sensors specific for the heating system. + description: One of `generic`, `gas`, `heatpump` or `fuelcell`. Specifying the heating_type provides additional attributes and sensors specific for the heating system. required: false type: string default: generic From cb33533358d7511b045af89cce2ae76a65dce380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Wed, 31 Mar 2021 12:46:23 +0200 Subject: [PATCH 72/90] Adjust version documentation (#17206) --- source/_integrations/version.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/_integrations/version.markdown b/source/_integrations/version.markdown index 78290968210..d29c9b63e1f 100644 --- a/source/_integrations/version.markdown +++ b/source/_integrations/version.markdown @@ -34,17 +34,17 @@ name: type: string default: "`Current Version` in case of `source: local`, `Latest Version` otherwise." beta: - description: Flag to indicate that it will check for beta versions, only supported for the sources `pypi`, `hassio` and `docker`. + description: Flag to indicate that it will check for beta versions, only supported for the sources `pypi`, `supervisor` and `container`. required: false type: boolean default: false image: - description: The image you want to check against, this is only supported for `hassio` and `docker`, see full list under. + description: The image you want to check against, this is only supported for `supervisor` and `container`, see full list under. required: false type: string default: default source: - description: The source you want to check against, possible values are `local`, `pypi`, `hassio`, `haio` and `docker`. + description: The source you want to check against, possible values are `local`, `pypi`, `supervisor`, `haio` and `container`. required: false type: string default: local From 3568a20ff5e8180ebfbed6cf763ce424862c56cf Mon Sep 17 00:00:00 2001 From: jjlawren Date: Wed, 31 Mar 2021 06:57:27 -0500 Subject: [PATCH 73/90] Describe new Plex library sensors (#17145) --- source/_integrations/plex.markdown | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/_integrations/plex.markdown b/source/_integrations/plex.markdown index a0c94c05360..a357797e9df 100644 --- a/source/_integrations/plex.markdown +++ b/source/_integrations/plex.markdown @@ -15,7 +15,7 @@ ha_platforms: - sensor --- -The Plex integration allows you to connect Home Assistant to a [Plex Media Server](https://plex.tv). Once configured, actively streaming [Plex Clients](https://www.plex.tv/apps-devices/) show up as [Media Players](/integrations/media_player/) and report playback status via a [Sensor](/integrations/sensor/) in Home Assistant. Media Players will allow you to control media playback and see the current playing item. +The Plex integration allows you to connect Home Assistant to a [Plex Media Server](https://plex.tv). Once configured, actively streaming [Plex Clients](https://www.plex.tv/apps-devices/) show up as [Media Players](/integrations/media_player/) and report playback status and library sizes via [Sensors](/integrations/sensor/) in Home Assistant. Media Players will allow you to control media playback and see the current playing item. Support for playing music directly on linked [Sonos](/integrations/sonos/) speakers is available for users with an active [Plex Pass](https://www.plex.tv/plex-pass/) subscription. More information [here](#sonos-playback). @@ -56,7 +56,16 @@ Alternatively, you can manually configure a Plex server connection by selecting ## Sensor -The Plex sensor platform monitors activity on a given Plex Media Server. The sensor state provides the a count of users currently watching media from the Plex server. Clicking the sensor shows who is watching what media. +The activity sensor provides a count of users currently watching media from the Plex server. Clicking the sensor shows details for the active users and media streams. + +The library sensors show a count of items in each library. Depending on the library contents, the sensor will show extra detail in its attributes. For example, a library sensor for TV shows will represent the total number of episodes in the library and its attributes will also report the number of shows and seasons it contains. + +
    + +The library sensors are disabled by default, but can be enabled via the Plex integration page. + +
    + ## Media Player From a42cc9f1ab4d6e7bbcc7bbbd50aa5c5a962aa92d Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Wed, 31 Mar 2021 15:28:59 +0200 Subject: [PATCH 74/90] Mention `name` property for services.yaml (#16788) --- source/_integrations/python_script.markdown | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/_integrations/python_script.markdown b/source/_integrations/python_script.markdown index da46b52ff62..6a6312129e0 100644 --- a/source/_integrations/python_script.markdown +++ b/source/_integrations/python_script.markdown @@ -76,12 +76,13 @@ The above `python_script` can be called using the following YAML as an input. ## Documenting your Python scripts -You can add descriptions for your Python scripts that will be shown in the Call Services tab of the Developer Options page. To do so, simply create a `services.yaml` file in your `/python_scripts` folder. Using the above Python script as an example, the `services.yaml` file would look like: +You can add names and descriptions for your Python scripts that will be shown in the frontend. To do so, simply create a `services.yaml` file in your `/python_scripts` folder. Using the above Python script as an example, the `services.yaml` file would look like: ```yaml # services.yaml turn_on_light: - description: Turn on a light and set its color. + name: Turn on light + description: Turn on a specific light and set its color. fields: entity_id: description: The light that will be turned on. From a3887c634a7a5715ea1ac562f270c4986dd73091 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 31 Mar 2021 06:22:45 -1000 Subject: [PATCH 75/90] Update docs for homekit spec compliance (#17166) --- source/_integrations/homekit.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_integrations/homekit.markdown b/source/_integrations/homekit.markdown index 947a7f8e572..92939cd5a21 100644 --- a/source/_integrations/homekit.markdown +++ b/source/_integrations/homekit.markdown @@ -307,7 +307,7 @@ It is recommended to only edit a HomeKit instance in the UI that was created in ### Accessory mode -When exposing a Camera, Activity based remote (a `remote` that supports activities), or Television media player (a `media_player` with device class `tv`) to HomeKit, `mode` must be set to `accessory`, and the include filter should be setup to only include a single entity. +When exposing a Camera, Activity based remote (a `remote` that supports activities), Lock, or Television media player (a `media_player` with device class `tv`) to HomeKit, `mode` must be set to `accessory`, and the include filter should be setup to only include a single entity. To quickly add all accessory modes entities in the UI: From 297febb1eb9adbcc93486954435230bb018cf175 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Wed, 31 Mar 2021 23:33:07 +0200 Subject: [PATCH 76/90] Beta release notes for 2021.4 (#17186) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Joakim Sørensen --- CODEOWNERS | 17 +- _config.yml | 6 +- source/_integrations/analytics.markdown | 3 +- source/_integrations/asuswrt.markdown | 1 + source/_integrations/blink.markdown | 1 + source/_integrations/broadlink.markdown | 1 + source/_integrations/econet.markdown | 1 + source/_integrations/faa_delays.markdown | 2 + source/_integrations/freebox.markdown | 1 + source/_integrations/gogogate2.markdown | 1 + source/_integrations/hdmi_cec.markdown | 2 - source/_integrations/hive.markdown | 1 + .../_integrations/home_plus_control.markdown | 2 + .../_integrations/homematicip_cloud.markdown | 2 - source/_integrations/panasonic_viera.markdown | 2 + source/_integrations/philips_js.markdown | 2 + source/_integrations/screenlogic.markdown | 27 +- source/_integrations/solaredge.markdown | 2 + source/_integrations/somfy_mylink.markdown | 2 - source/_integrations/stream.markdown | 1 + source/_integrations/vera.markdown | 2 +- source/_integrations/wake_on_lan.markdown | 2 + source/_integrations/zha.markdown | 1 + .../_posts/2021-04-07-release-20214.markdown | 2397 +++++++++++++++++ source/images/blog/2021-04/social.png | Bin 0 -> 99174 bytes 25 files changed, 2446 insertions(+), 33 deletions(-) create mode 100644 source/_posts/2021-04-07-release-20214.markdown create mode 100644 source/images/blog/2021-04/social.png diff --git a/CODEOWNERS b/CODEOWNERS index 015522cb2cc..c6999386086 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -26,6 +26,7 @@ source/_integrations/alpha_vantage.markdown @fabaff source/_integrations/ambiclimate.markdown @danielhiversen source/_integrations/ambient_station.markdown @bachya source/_integrations/amcrest.markdown @pnbruckner +source/_integrations/analytics.markdown @home-assistant/core @ludeeus source/_integrations/androidtv.markdown @JeffLIrion source/_integrations/apache_kafka.markdown @bachya source/_integrations/api.markdown @home-assistant/core @@ -36,7 +37,7 @@ source/_integrations/arcam_fmj.markdown @elupus source/_integrations/arduino.markdown @fabaff source/_integrations/arest.markdown @fabaff source/_integrations/arris_tg2492lg.markdown @vanbalken -source/_integrations/asuswrt.markdown @kennedyshead +source/_integrations/asuswrt.markdown @kennedyshead @ollo69 source/_integrations/atag.markdown @MatsNL source/_integrations/aten_pe.markdown @mtdcr source/_integrations/atome.markdown @baqs @@ -135,7 +136,7 @@ source/_integrations/esphome.markdown @OttoWinter source/_integrations/essent.markdown @TheLastProject source/_integrations/evohome.markdown @zxdavb source/_integrations/ezviz.markdown @baqs -source/_integrations/faadelays.markdown @ntilley905 +source/_integrations/faa_delays.markdown @ntilley905 source/_integrations/fastdotcom.markdown @rohankapoorcom source/_integrations/file.markdown @fabaff source/_integrations/filter.markdown @dgomes @@ -169,13 +170,11 @@ source/_integrations/google_cloud.markdown @lufton source/_integrations/gpsd.markdown @fabaff source/_integrations/gree.markdown @cmroche source/_integrations/greeneye_monitor.markdown @jkeljo -source/_integrations/griddy.markdown @bdraco source/_integrations/group.markdown @home-assistant/core source/_integrations/growatt_server.markdown @indykoning source/_integrations/guardian.markdown @bachya source/_integrations/habitica.markdown @ASMfreaK @leikoilja source/_integrations/harmony.markdown @ehendrix23 @bramkragten @bdraco @mkeesey -source/_integrations/hdmi_cec.markdown @newAM source/_integrations/heatmiser.markdown @andylockran source/_integrations/heos.markdown @andrewsayre source/_integrations/here_travel_time.markdown @eifinger @@ -186,11 +185,11 @@ source/_integrations/history.markdown @home-assistant/core source/_integrations/hive.markdown @Rendili @KJonline source/_integrations/hlk_sw16.markdown @jameshilliard source/_integrations/home_connect.markdown @DavidMStraub +source/_integrations/home_plus_control.markdown @chemaaa source/_integrations/homeassistant.markdown @home-assistant/core source/_integrations/homekit.markdown @bdraco source/_integrations/homekit_controller.markdown @Jc2k source/_integrations/homematic.markdown @pvizeli @danielperna84 -source/_integrations/homematicip_cloud.markdown @SukramJ source/_integrations/http.markdown @home-assistant/core source/_integrations/huawei_lte.markdown @scop @fphammerle source/_integrations/huawei_router.markdown @abmantis @@ -388,6 +387,7 @@ source/_integrations/samsungtv.markdown @escoand source/_integrations/scene.markdown @home-assistant/core source/_integrations/schluter.markdown @prairieapps source/_integrations/scrape.markdown @fabaff +source/_integrations/screenlogic.markdown @dieselrabbit source/_integrations/script.markdown @home-assistant/core source/_integrations/search.markdown @home-assistant/core source/_integrations/sense.markdown @kbickar @@ -418,12 +418,12 @@ source/_integrations/smarttub.markdown @mdz source/_integrations/smarty.markdown @z0mbieprocess source/_integrations/sms.markdown @ocalvo source/_integrations/smtp.markdown @fabaff +source/_integrations/solaredge.markdown @frenck source/_integrations/solaredge_local.markdown @drobtravels @scheric source/_integrations/solarlog.markdown @Ernst79 source/_integrations/solax.markdown @squishykid source/_integrations/soma.markdown @ratsept source/_integrations/somfy.markdown @tetienne -source/_integrations/somfy_mylink.markdown @bdraco source/_integrations/sonarr.markdown @ctalkington source/_integrations/songpal.markdown @rytilahti @shenxn source/_integrations/sonos.markdown @cgtobi @@ -439,7 +439,7 @@ source/_integrations/starline.markdown @anonym-tsk source/_integrations/statistics.markdown @fabaff source/_integrations/stiebel_eltron.markdown @fucm source/_integrations/stookalert.markdown @fwestenberg -source/_integrations/stream.markdown @hunterjm @uvjustin +source/_integrations/stream.markdown @hunterjm @uvjustin @allenporter source/_integrations/stt.markdown @pvizeli source/_integrations/subaru.markdown @G-Two source/_integrations/suez_water.markdown @ooii @@ -497,7 +497,7 @@ source/_integrations/usgs_earthquakes_feed.markdown @exxamalte source/_integrations/utility_meter.markdown @dgomes source/_integrations/velbus.markdown @Cereal2nd @brefra source/_integrations/velux.markdown @Julius2342 -source/_integrations/vera.markdown @vangorra +source/_integrations/vera.markdown @pavoni source/_integrations/verisure.markdown @frenck source/_integrations/versasense.markdown @flamm3blemuff1n source/_integrations/version.markdown @fabaff @ludeeus @@ -509,6 +509,7 @@ source/_integrations/vizio.markdown @raman325 source/_integrations/vlc_telnet.markdown @rodripf @dmcc source/_integrations/volkszaehler.markdown @fabaff source/_integrations/volumio.markdown @OnFreund +source/_integrations/wake_on_lan.markdown @ntilley905 source/_integrations/waqi.markdown @andrey-git source/_integrations/watson_tts.markdown @rutkai source/_integrations/weather.markdown @fabaff diff --git a/_config.yml b/_config.yml index 8493dcd17c4..9fb16d0b8e7 100644 --- a/_config.yml +++ b/_config.yml @@ -105,9 +105,9 @@ social: # Home Assistant release details current_major_version: 2021 -current_minor_version: 3 -current_patch_version: 4 -date_released: 2021-03-12 +current_minor_version: 4 +current_patch_version: 0 +date_released: 2021-04-07 # Either # or the anchor link to latest release notes in the blog post. # Must be prefixed with a # and have double quotes around it. diff --git a/source/_integrations/analytics.markdown b/source/_integrations/analytics.markdown index ea825bea113..c8068b5dba3 100644 --- a/source/_integrations/analytics.markdown +++ b/source/_integrations/analytics.markdown @@ -3,11 +3,12 @@ title: Analytics description: Share system analytics and diagnostics ha_category: - Other -ha_release: 2021.4 +ha_release: 2021.4 ha_iot_class: Cloud Push ha_quality_scale: internal ha_codeowners: - '@home-assistant/core' + - '@ludeeus' ha_domain: analytics --- diff --git a/source/_integrations/asuswrt.markdown b/source/_integrations/asuswrt.markdown index 5f64d7ff796..66362a1b61d 100644 --- a/source/_integrations/asuswrt.markdown +++ b/source/_integrations/asuswrt.markdown @@ -10,6 +10,7 @@ ha_config_flow: true ha_iot_class: Local Polling ha_codeowners: - '@kennedyshead' + - '@ollo69' ha_domain: asuswrt ha_platforms: - device_tracker diff --git a/source/_integrations/blink.markdown b/source/_integrations/blink.markdown index 0b7f1781d19..51b179625e3 100644 --- a/source/_integrations/blink.markdown +++ b/source/_integrations/blink.markdown @@ -18,6 +18,7 @@ ha_platforms: - binary_sensor - camera - sensor +ha_dhcp: true --- The `blink` integration lets you view camera images and motion events from [Blink](https://blinkforhome.com/) camera and security systems. diff --git a/source/_integrations/broadlink.markdown b/source/_integrations/broadlink.markdown index 5b566577ea5..7cbfe6f0e78 100644 --- a/source/_integrations/broadlink.markdown +++ b/source/_integrations/broadlink.markdown @@ -16,6 +16,7 @@ ha_platforms: - remote - sensor - switch +ha_dhcp: true --- The Broadlink integration allows you to control and monitor Broadlink universal remotes, smart plugs, power strips, switches and sensors. The following devices are supported: diff --git a/source/_integrations/econet.markdown b/source/_integrations/econet.markdown index de6cc6b9b82..f959af9625c 100644 --- a/source/_integrations/econet.markdown +++ b/source/_integrations/econet.markdown @@ -15,6 +15,7 @@ ha_codeowners: ha_config_flow: true ha_platforms: - binary_sensor + - climate - sensor - water_heater --- diff --git a/source/_integrations/faa_delays.markdown b/source/_integrations/faa_delays.markdown index 0944ed0f709..fe05ca40808 100644 --- a/source/_integrations/faa_delays.markdown +++ b/source/_integrations/faa_delays.markdown @@ -9,6 +9,8 @@ ha_config_flow: true ha_codeowners: - '@ntilley905' ha_domain: faa_delays +ha_platforms: + - binary_sensor --- The FAA Delays integration collects and displays information about delays at US Airports based on the diff --git a/source/_integrations/freebox.markdown b/source/_integrations/freebox.markdown index 364250df6a1..adad0c2c4c5 100644 --- a/source/_integrations/freebox.markdown +++ b/source/_integrations/freebox.markdown @@ -17,6 +17,7 @@ ha_platforms: - device_tracker - sensor - switch +ha_zeroconf: true --- The `freebox` integration allows you to observe and control [Freebox router](https://www.free.fr/). diff --git a/source/_integrations/gogogate2.markdown b/source/_integrations/gogogate2.markdown index 3f48a2cc060..075a929c094 100644 --- a/source/_integrations/gogogate2.markdown +++ b/source/_integrations/gogogate2.markdown @@ -13,6 +13,7 @@ ha_config_flow: true ha_homekit: true ha_platforms: - cover + - sensor --- The `gogogate2` cover platform lets you control Gogogate2 and iSmartGate enabled garage doors and gates through Home Assistant. Device names in Home Assistant are generated based on the names defined in the GogoGate2 or iSmartGate mobile app. diff --git a/source/_integrations/hdmi_cec.markdown b/source/_integrations/hdmi_cec.markdown index 0922b95aec6..0f536da635f 100644 --- a/source/_integrations/hdmi_cec.markdown +++ b/source/_integrations/hdmi_cec.markdown @@ -6,8 +6,6 @@ ha_category: ha_release: 0.23 ha_iot_class: Local Push ha_domain: hdmi_cec -ha_codeowners: - - '@newAM' ha_platforms: - switch --- diff --git a/source/_integrations/hive.markdown b/source/_integrations/hive.markdown index 47e9b5b6c75..140dfe55f37 100644 --- a/source/_integrations/hive.markdown +++ b/source/_integrations/hive.markdown @@ -22,6 +22,7 @@ ha_platforms: - sensor - switch - water_heater +ha_config_flow: true --- The Hive integration for Home Assistant allows you to interact with supported devices and services offered by diff --git a/source/_integrations/home_plus_control.markdown b/source/_integrations/home_plus_control.markdown index e1e197ad441..4ad115acc66 100644 --- a/source/_integrations/home_plus_control.markdown +++ b/source/_integrations/home_plus_control.markdown @@ -9,6 +9,8 @@ ha_codeowners: - '@chemaaa' ha_config_flow: true ha_domain: home_plus_control +ha_platforms: + - switch --- The Home+ Control integration platform allows you to control a range of Legrand in-wall switches and power outlets that have smart home functionality thanks to their "with Netatmo" capabilities. diff --git a/source/_integrations/homematicip_cloud.markdown b/source/_integrations/homematicip_cloud.markdown index 3c874146ee5..20e59526ca9 100644 --- a/source/_integrations/homematicip_cloud.markdown +++ b/source/_integrations/homematicip_cloud.markdown @@ -14,8 +14,6 @@ ha_iot_class: Cloud Push ha_release: 0.66 ha_config_flow: true ha_quality_scale: platinum -ha_codeowners: - - '@SukramJ' ha_domain: homematicip_cloud ha_platforms: - alarm_control_panel diff --git a/source/_integrations/panasonic_viera.markdown b/source/_integrations/panasonic_viera.markdown index 6614b86464c..6f26a5cdb3d 100644 --- a/source/_integrations/panasonic_viera.markdown +++ b/source/_integrations/panasonic_viera.markdown @@ -8,6 +8,8 @@ ha_release: 0.17 ha_iot_class: Local Polling ha_domain: panasonic_viera ha_config_flow: true +ha_platforms: + - remote --- The `panasonic_viera` platform allows you to control a Panasonic Viera TV. diff --git a/source/_integrations/philips_js.markdown b/source/_integrations/philips_js.markdown index 72edbaac1b2..b6e0f0e7886 100644 --- a/source/_integrations/philips_js.markdown +++ b/source/_integrations/philips_js.markdown @@ -10,6 +10,8 @@ ha_codeowners: - '@elupus' ha_domain: philips_js ha_config_flow: true +ha_platforms: + - remote --- The `philips_js` platform allows you to control Philips TVs which expose the [jointSPACE](http://jointspace.sourceforge.net/) JSON-API. diff --git a/source/_integrations/screenlogic.markdown b/source/_integrations/screenlogic.markdown index 866349f6c7a..b4fa49dc7d6 100644 --- a/source/_integrations/screenlogic.markdown +++ b/source/_integrations/screenlogic.markdown @@ -1,25 +1,24 @@ --- -title: "Pentair ScreenLogic" -description: "Instructions on how to integrate a ScreenLogic gateway within Home Assistant." -ha_release: "2021.4" +title: Pentair ScreenLogic +description: Instructions on how to integrate a ScreenLogic gateway within Home Assistant. +ha_release: '2021.4' ha_category: - - Hub - - Binary Sensor - - Climate - - Sensor - - Switch -ha_iot_class: "Local Polling" -ha_quality_scale: gold + - Hub + - Binary Sensor + - Climate + - Sensor + - Switch +ha_iot_class: Local Polling ha_config_flow: true ha_dhcp: true ha_codeowners: - '@dieselrabbit' ha_domain: screenlogic ha_platforms: - - binary_sensor - - climate - - sensor - - switch + - binary_sensor + - climate + - sensor + - switch --- The Pentair ScreenLogic integration allows you to integrate your Pentair Intellitouch or EasyTouch pool controller with Home Assistant via the [Pentair ScreenLogic](https://www.pentair.com/en-us/products/residential/pool-spa-equipment/pool-automation/screenlogic2_interfaceforintellitouchandeasytouchautomationsystems.html) gateway. diff --git a/source/_integrations/solaredge.markdown b/source/_integrations/solaredge.markdown index e5142687868..d3597d51845 100644 --- a/source/_integrations/solaredge.markdown +++ b/source/_integrations/solaredge.markdown @@ -10,6 +10,8 @@ ha_domain: solaredge ha_dhcp: true ha_platforms: - sensor +ha_codeowners: + - '@frenck' --- The `solaredge` platform uses the [SolarEdge Monitoring API](https://www.solaredge.com/sites/default/files/se_monitoring_api.pdf) to allow you to get details from your SolarEdge solar power setup and integrate these in your Home Assistant installation. diff --git a/source/_integrations/somfy_mylink.markdown b/source/_integrations/somfy_mylink.markdown index 0fed59e43fb..61020e115f7 100644 --- a/source/_integrations/somfy_mylink.markdown +++ b/source/_integrations/somfy_mylink.markdown @@ -8,8 +8,6 @@ ha_release: 0.92 ha_iot_class: Assumed State ha_domain: somfy_mylink ha_config_flow: true -ha_codeowners: - - '@bdraco' ha_dhcp: true ha_platforms: - cover diff --git a/source/_integrations/stream.markdown b/source/_integrations/stream.markdown index 9ec204ba39c..c0b11865287 100644 --- a/source/_integrations/stream.markdown +++ b/source/_integrations/stream.markdown @@ -9,6 +9,7 @@ ha_quality_scale: internal ha_codeowners: - '@hunterjm' - '@uvjustin' + - '@allenporter' ha_domain: stream --- diff --git a/source/_integrations/vera.markdown b/source/_integrations/vera.markdown index d2d46bf24ec..e9a1513d254 100644 --- a/source/_integrations/vera.markdown +++ b/source/_integrations/vera.markdown @@ -16,7 +16,7 @@ ha_iot_class: Local Polling ha_config_flow: true ha_domain: vera ha_codeowners: - - '@vangorra' + - '@pavoni' ha_platforms: - binary_sensor - climate diff --git a/source/_integrations/wake_on_lan.markdown b/source/_integrations/wake_on_lan.markdown index 31e1c48fe88..052703a0023 100644 --- a/source/_integrations/wake_on_lan.markdown +++ b/source/_integrations/wake_on_lan.markdown @@ -9,6 +9,8 @@ ha_iot_class: Local Push ha_domain: wake_on_lan ha_platforms: - switch +ha_codeowners: + - '@ntilley905' --- The `wake_on_lan` integration enables the ability to send _magic packets_ to [Wake on LAN](https://en.wikipedia.org/wiki/Wake-on-LAN) capable devices to turn them on. diff --git a/source/_integrations/zha.markdown b/source/_integrations/zha.markdown index 94cffadd918..e200bc50491 100644 --- a/source/_integrations/zha.markdown +++ b/source/_integrations/zha.markdown @@ -30,6 +30,7 @@ ha_platforms: - lock - sensor - switch +ha_zeroconf: true --- The ZHA (Zigbee Home Automation) integration allows you to connect many off-the-shelf [Zigbee based devices](https://zigbeealliance.org) directly to Home Assistant, using one of the many available Zigbee coordinators. diff --git a/source/_posts/2021-04-07-release-20214.markdown b/source/_posts/2021-04-07-release-20214.markdown new file mode 100644 index 00000000000..23d2e531812 --- /dev/null +++ b/source/_posts/2021-04-07-release-20214.markdown @@ -0,0 +1,2397 @@ +--- +layout: post +title: "2021.4: For our advanced users ❤️ (Beta release notes)" +description: "The beta release notes for the upcoming Home Assistant Core 2021.4 release." +date: 2021-3-31 00:00:00 +date_formatted: "April 7, 2021" +author: Franck Nijhof +author_twitter: frenck +comments: true +categories: +- Release-Notes +- Core +og_image: /images/blog/2021-04/social.png +feedback: true +--- + + + +These are the beta release notes for Home Assistant Core 2021.4 (and is thus a +work in progress). + +If you encounter any issues with the beta release, please report them on GitHub: + +- Issues with integrations, automations and such (Core related):
    + +- Issues with the frontend/Lovelace:
    + +- Issues with the Supervisor:
    + +- Issues with the documentation:
    + + +Please be sure to include the beta version you are running in the issue +description (not title), so we can classify your issue correctly. + +Issues introduced in the beta are processed with priority. + +- [Automation debugging](#automation-debugging) +- [Home Assistant Analytics](#home-assistant-analytics) +- [Filtering automations, scripts and scenes](#filtering-automations-scripts-and-scenes) +- [Z-Wave JS update](#z-wave-js-update) +- [Trigger-based template sensors](#trigger-based-template-sensors) +- [UI selectors for script fields](#ui-selectors-for-script-fields) +- [Other noteworthy changes](#other-noteworthy-changes) +- [New Integrations](#new-integrations) +- [New Platforms](#new-platforms) +- [Integrations now available to set up from the UI](#integrations-now-available-to-set-up-from-the-ui) +- [If you need help...](#if-you-need-help) +- [Breaking Changes](#breaking-changes) +- [Farewell to the following](#farewell-to-the-following) +- [All changes](#all-changes) + +## Automation debugging + +Wait, why didn't that light turn on? Why isn't the thermostat adjusted? +Why is this automation not working? What is going on here?! This is a haunted +house!?! + +Sounds familiar? I'm sure we all had these moment, but are you ready for this? +We can now debug automations! + + + +View details on previous automation runs, and see details on each step to +explore what happened. + +TODO: +- Add screenshots / recordings +- Thank everybody involved in this, Erik, Paulus, Bram, Thomas this is awesome! +- More body to the paragraph + + + +## Home Assistant Analytics + +Now don't be scared by the title! + +Today we introduce, Home Assistant Analytics. Opt-in, privacy aware, public +and open source. Just as it all should be for our project. + +Ludeeus did an amazing job writing this new integration. You decide if you turn +it on or not; however, we guarantee its privacy aware. Doubt it? Review it! +Everything is open source! + +Not open enough for you? Well, maybe you want to view the public result: + + + +So why do we do this? Well, it helps the project and all contributors to +see things like: Most used integrations. This can greatly help with improving +project priorities. + +"But the updater did this already, right?" Yes, well, thing has been broken +actually. So while we had some data, it was barely usable (actually not useable +at all). Instead of fixing the updater, we now have a better solution that +better matches our project goals. The update still exists, it now just does one +single thing: Showing if an update is available. + +TODO: +- Improve text +- Add screenshot or embed analytics? +- Instructions on how to activate? +- Link to documentation + +## Filtering automations, scripts and scenes + +Categorizing things like automations, is definitely one of the most requested +things in our history. This became clear again during last years month of +what the heck and in various issues/discussions/feature requests. + +Suggestions for labels, folders, and many more have been created. However, +we already have some great categorizing features in Home Assistant itself: + +Devices & Areas + +As of today, you can filter your automations, scripts and scenes based on +the device or area they are put in, or affect. Not only can you now +show show the automations that are used in your living room area, but you can +also filter automations with just the ones that touch your thermostat. + +TODO: +- Add screenshot +- Improve text + +## Z-Wave JS update + +You can now configure each device. When you view a device in the Home +Assistant frontend, you can click on "CONFIGURE DEVICE" to manage and adjust +device (node) specific configuration parameters for the selected device. + +Furthermore two new services are introduced: + +- `zwave_js.bulk_set_partial_config_parameters` +- `zwave_js.set_value` + +TODO: +- Add more text to this +- Add screenshot +- Missing Z-Wave updates? + +## Trigger-based template sensors + +This release adds initial support for pretty advanced new feature, that can +be really helpful. Sensors, that are updated based on triggers and the +data that comes with it. + +{% raw %} +```yaml +# Example configuration entry +template: + - trigger: + - platform: webhook + webhook_id: my-super-secret-webhook-id + sensor: + - name: "Webhook Temperature" + state: "{{ trigger.json.temperature }}" + - name: "Webhook Humidity" + state: "{{ trigger.json.humidity }}" +``` + +{% endraw %} + +You can test this trigger entity with the following CURL command: + +```bash +curl --header "Content-Type: application/json" \ + --request POST \ + --data '{"temperature": 5, "humidity": 34}' \ + http://homeassistant.local:8123/api/webhook/my-super-secret-webhook-id +``` + +TODO: +- Extend story +- Clean up/simplify example +- Note on sensor only at this point, hopefully more soon! + +## UI selectors for script fields + +You can now use UI Selectors for you scripts field parameters. This +brings UI capabilities to scripts. It works both in the dev tools -> services, +but also in the automation UI. + +Example: +Selectors: +More extensive service description example: + +TODO: +- Improve documentation. I noticed when linking this, that documentation around + fields is low. +- Screenshot +- More text +- Example? + +## Other noteworthy changes + +There is much more juice in this release; here are some of the other +noteworthy changes this release: + +- Lorem ipsum, thanks to [@frenck]! ;) +- TODO with items from below. + +To format, candidates from the backend: + +- Add Xiaomi Miio fan config flow ([@starkillerOG] - [#46866]) ([xiaomi_miio docs]) (breaking-change) +- Add remote control platform to Panasonic Viera ([@joogps] - [#42450]) ([panasonic_viera docs]) (new-platform) +- Add zeroconf discovery to Freebox ([@Quentame] - [#47045]) ([discovery docs]) ([freebox docs]) +- Add suggested_area support to devolo Home Control ([@Shutgun] - [#47063]) ([devolo_home_control docs]) +- Add hassio addon_update service and hassio config entry with addon and OS devices and entities ([@raman325] - [#46342]) ([hassio docs]) (new-platform) +- Add support for a list of known hosts to Google Cast ([@emontnemery] - [#47232]) ([cast docs]) +- Add remote control support to philips_js ([@elupus] - [#47249]) ([philips_js docs]) (new-platform) +- Add battery sensor for gogogate2 wireless door sensor ([@emontnemery] - [#47145]) ([gogogate2 docs]) (new-platform) +- Add services for izone airflow min/max ([@Nick-Adams-AU] - [#45727]) ([izone docs]) +- Add force_update to tasmota sensors ([@rlehfeld] - [#47052]) ([tasmota docs]) +- Add suggested_area support to Apple TV ([@bdraco] - [#47015]) ([apple_tv docs]) +- Add Tado weather support ([@Noltari] - [#44807]) ([tado docs]) (new-platform) +- Fix light brightness_step on multiple entities ([@emontnemery] - [#47746]) ([light docs]) +- Hoist mqtt name property and add icon support to MqttEntity ([@kristianheljas] - [#47165]) ([mqtt docs]) +- Add apply_filter attribute to recorder.purge service ([@cdce8p] - [#45826]) ([recorder docs]) +- Add HomeKit support for new CO / CO2 device class ([@iMicknl] - [#47737]) ([demo docs]) ([homekit docs]) +- Add device_info to Apple TV entities ([@postlund] - [#47837]) ([apple_tv docs]) +- Verisure: Remove JSONPath, unique IDs, small cleanups ([@frenck] - [#47870]) ([verisure docs]) +- Add suggested area support to august ([@bdraco] - [#47930]) ([august docs]) +- Support all Xiaomi Miio gateway switches ([@starkillerOG] - [#46657]) ([xiaomi_miio docs]) +- Add suggested_area to MQTT discovery ([@RadekHvizdos] - [#47903]) ([mqtt docs]) +- Add config flow to Verisure ([@frenck] - [#47880]) ([verisure docs]) (breaking-change) +- Move Verisure services to entity services ([@frenck] - [#47905]) ([verisure docs]) (breaking-change) +- Add devices to Verisure integration ([@frenck] - [#47913]) ([verisure docs]) +- Add reauthentication to Verisure ([@frenck] - [#47972]) ([verisure docs]) +- Add support for light color modes ([@emontnemery] - [#47720]) ([kulersky docs]) ([light docs]) ([yeelight docs]) ([zerproc docs]) +- Add device classes to Verisure sensors ([@frenck] - [#47990]) ([verisure docs]) +- Add definitions for grouping media players ([@klada] - [#41193]) ([media_player docs]) +- Add Opentherm Gateway current and setpoint precision ([@Martidjen] - [#47484]) ([opentherm_gw docs]) +- Warn on undefined variables in templates ([@emontnemery] - [#48140]) (breaking-change) +- Add an option to hide selected Hyperion effects ([@dermotduffy] - [#45689]) ([hyperion docs]) +- Improve Docker and Kubernetes support for KNX ([@plomosits] - [#48065]) ([knx docs]) +- Add august doorbells to dhcp discovery ([@bdraco] - [#48244]) ([august docs]) +- Add dhcp discovery support to blink ([@bdraco] - [#48243]) ([blink docs]) +- Add Ambient Station PM25 indoor sensor ([@conflipper] - [#47970]) ([ambient_station docs]) +- Add broadlink dhcp discovery ([@bdraco] - [#48408]) ([broadlink docs]) +- Add dsmr monthly and yearly totals ([@robertdelpeut] - [#48253]) ([dsmr_reader docs]) +- Add support for Selectors in Script service fields ([@frenck] - [#48469]) ([script docs]) +- Allow specifying template entities based on triggers ([@balloob] - [#48169]) ([trigger docs]) (new-integration) +- Command template support for MQTT fan ([@jbouwh] - [#48413]) ([mqtt docs]) (breaking-change) +- Add image proxy to Kodi media browser ([@cgtobi] - [#47315]) ([kodi docs]) +- Add opentherm_gw option for setpoint override mode ([@Martidjen] - [#48465]) ([opentherm_gw docs]) +- Add zwave_js.set_value service ([@raman325] - [#48487]) ([zwave_js docs]) +- Add support for capturing renewals to dhcp discovery ([@bdraco] - [#48242]) ([dhcp docs]) +- KNX passive group addresses ([@farmio] - [#48009]) ([knx docs]) +- Add regex-based filters to logger component ([@jshufro] - [#48439]) ([logger docs]) +- Add color_mode support to MQTT JSON light ([@emontnemery] - [#47993]) ([light docs]) ([mqtt docs]) (breaking-change) +- Add Plex library count sensors ([@jjlawren] - [#48339]) ([plex docs]) +- KNX entities now have a unique_id, so can be used in the frontend ([@marvin-w] - [#48522]) ([knx docs]) +- Add operation sensor to Shelly Gas ([@chemelli74] - [#48462]) ([shelly docs]) +- Add Qingping Air Monitor Lite support support ([@arturdobo] - [#48181]) ([xiaomi_miio docs]) (new-integration) + +To format, candidates from the frontend: + +- Number format options in your user profile! (?) @? +- Enable turning off edit mode in panel views (#8625) @thomasloven +- Quick Bar: Use command category labels instead of icons (#7692) @donkawechico +- Fix rendering when selecting all in datatable (#8749) @bramkragten +- Add filtering by devices/areas to scripts (#8748) @bramkragten +- Add filtering by devices/areas to scenes (#8747) @bramkragten +- Add filtering to automaton overview (#8736) @bramkragten +- Show if config entry is not loaded (#8717) @bramkragten + +## New Integrations + +We welcome the following new integrations this release: + +- [Analytics][analytics docs], added by [@ludeeus] +- [Legrand Home+ Control][homepluscontrol docs], added by [@chemaaa] +- [Pentair ScreenLogic][screenlogic docs], added by [@dieselrabbit] + +## New Platforms + +The following integration got support for a new platform: + +- [Gogogate2 and iSmartGate][gogogate2 docs] provides battery sensors for wiresless door sensors, added by [@emontnemery] +- [Panasonic Viera][panasonic_viera docs] has now support for remotes, added by [@joogps] +- [Philips TV][philips_js docs] now has support for remotes, added by [@elupus] +- [Rheem EcoNet Products] now have support for climate entities, added by [@w1ll1am23]. +- [Supervisor][hassio docs] integration now has entities and services for things like versions and pending updates, added by [@raman325] +- [Tado] now has weather support, added by [@Noltari] + +## Integrations now available to set up from the UI + +The following integrations are now available via the Home Assistant UI: + +- [Xiaomi Miio][xiaomi_miio docs], fans, sensors and lights, done by [@starkillerOG] + +## If you need help... + +...don't hesitate to use our very active [forums](https://community.home-assistant.io/) or join us for a little [chat](https://discord.gg/c5DvZ4e). + +Experiencing issues introduced by this release? Please report them in our [issue tracker](https://github.com/home-assistant/core/issues). Make sure to fill in all fields of the issue template. + + + +## Breaking Changes + +Below is a listing of the breaking change for this release, per subject or +integration. Click on one of those to read more about the breaking change +for that specific item. + +{% details "Custom integrations: Version warning" %} + +Custom integrations now require a `version` key in their manifest file, this +also means that all custom integrations now require a manifest file. + +If you are using a legacy custom integration like `custom_components/awesome.py` +this now needs to move to `custom_components/awesome/__init__.py` so you can +add `custom_components/awesome/manifest.json` to it. + +For more information about integration, manifests have a look here: + + +**For now, this will create a warning on startup.** But this will be +blocked from loading if it's missing a version in the manifest starting with Home Assistant 2021.6. + +**If you see these warnings, please report the issue with the author +of that custom integration.** + +([@ludeeus] - [#45919]) + +{% enddetails %} + +{% details "Xiaomi Miio" %} + +The Xiaomi Miio Fan, Sensor & Light platforms can now be configured via the +UI. + +If you currently have them configured using YAML configuration, they will +be automatically imported into the UI on upgrade. After upgrading, you can +safely remove the YAML configuration for these devices. + +([@starkillerOG] - [#46866] [#46964] [#47161]) ([xiaomi_miio docs]) + +{% enddetails %} + +{% details "KNX" %} + +The `config_file` YAML option for KNX is deprecated, please remove it from +your YAML configuration if you have it configured. + +Float types are no longer valid for sensor / expose sensor type because the +trailing zeros caused troubles when splitting to two integers. + +([@farmio] - [#46874] [#48005]) ([knx docs]) + +{% enddetails %} + +{% details "LIFX Legacy" %} + +The LIFX Legacy platform is deprecated and will be removed in Home Assistant +Core 2021.6.0. Use the LIFX integration instead. + +([@frenck] - [#47235]) ([lifx_legacy docs]) + +{% enddetails %} + +{% details "Secrets" %} + +At this moment, we are unsure if this is a breaking change or not, so we +list it, just to be sure. + +We are now explicitly only supporting secrets inside your Home Assistant Core +and Lovelace configuration files (and anything included from there). Secrets +are no longer supported in other loaded YAML files. + +([@balloob] - [#47034]) + +{% enddetails %} + +{% details "HomeKit" %} + +The HomeKit `auto_start` configuration option has been deprecated. It dates +from the "old"-days to prevent entities not being available yet when HomeKit +started. However, nowadays, Home Assistant ensures all entities are available +on startup instantly. + +Therefore, this option is no longer needed. If you still have it in your +configuration (and have automations for it to start HomeKit); those can be +safely removed as well. + +([@frenck] - [#47470]) ([homekit docs]) + +{% enddetails %} + +{% details "Hive" %} + +The Hive integration can now be configured via the UI and configuring it via +YAML is now deprecated. If you have an existing YAML configuration, +it will be automatically imported on upgrade. After the upgrade, +the YAML configuration can be safely removed. + +([@KJonline] - [#47300]) ([hive docs]) + +{% enddetails %} + +{% details "Wake On LAN" %} + +Wake on LAN component now assumes a dummy state if a host is not provided. +Before, the state was only based on the `host` config parameter, which is +listed as optional. + +With this change the `host` config is still optional, but if it is not defined, +the state of the switch is simply the last action that was taken. If you're +relying on a Wake on LAN entity in an automation or script, please make sure +that your assumptions about state still hold. + +([@ntilley905] - [#47719]) ([wake_on_lan docs]) + +{% enddetails %} + +{% details "Verisure" %} + +The Verisure integration largely rewritten and is now configured via the Home +Assistant user interface. + +Your existing YAML configuration will be automatically imported when upgrading +Home Assistant Core. After the upgrade completes, you can safely remove the +existing Verisure YAML configuration. + +If after upgrade your Verisure alarm system doesn't appear, please check your +[integrations dashboard](https://my.home-assistant.io/redirect/integrations/). +In rare cases (with accounts that have access to multiple Verisure alarm +systems), it might be needed to select the specific Verisure alarm system to +migrate. + +This also means the YAML configuration for the Verisure integration is now +deprecated and will be removed in Home Assistant Core 2021.6.0. + +The services provided by the Verisure integration have changed to match the +standard way of how Home Assistant handles services. The following services +are affected by this change: + +- {% my developer_call_service service="verisure.capture_smartcam" %} +- {% my developer_call_service service="verisure.disable_autolock" %} +- {% my developer_call_service service="verisure.enable_autolock" %} + +Previously these services required a `device_serial` parameter, they have now +changed to accept a regular Home Assistant entity, device or area as a target. +For example: + +```yaml +- service: verisure.enable_autolock + target: + entity_id: lock.my_verisure_lock +``` + +If you used any of these services in your automations or scripts, please make +sure you update them after updating to Home Assistant Core 2021.4.0. + +([@frenck] - [#47880] [#47905]) ([verisure docs]) + +{% enddetails %} + +{% details "Prometheus" %} + +Before this change, all sensors in an unknown state when the Prometheus exporter +starts (i.e.: when Home Assistant starts) were being setup and metrics were +exported with a default value of `0`. Now, they will not be exported anymore +(unless they become available again) - they can be found by searching for +metrics where `entity_available` is `0` (will reveal both entities that are +in unknown or unavailable state). + +You should update any automations, scripts or 3rd party data consumers that +depend on the old prometheus export with default value `0`. + +([@inetAnt] - [#47840]) ([prometheus docs]) + +{% enddetails %} + +{% details "August" %} + +August has fully transitioned to configuration via UI. YAML configuration is +no longer supported. Existing YAML configuration has already been imported +automatically in the previous releases and can now safely be removed from your +configuration files. + +([@bdraco] - [#47615]) ([august docs]) + +{% enddetails %} + +{% details "Workday" %} + +The Workday integration used to operate on the timezone configured on the +system, instead of the timezone configured in Home Assistant. This can become +problematic, for example, if your system runs on UTC, but you are 11 hours +ahead of that. + +This behavior has been correct and the workday sensors now rely on the timezone +configured in Home Assistant. You might need to adjust to this, if you have +automations, scripts or templates that previously manually corrected this. + +([@schiermi] - [#47927]) ([workday docs]) + +{% enddetails %} + +{% details "Ubiquiti UniFi Video" %} + +The datetime returned in the `last_recording_start_time` state attribute of the +uvc camera entity was changed from local time to be UTC time. All times in state +attributes must be UTC time. You should update any automations or scripts that +depends on this state attribute. + +([@sycx2] - [#41438]) ([uvc docs]) + +{% enddetails %} + +{% details "Z-Wave JS" %} + +Zwave JS climate devices that report their temperature in Fahrenheit will now +report in tenth precision instead of whole precision, when the device supports +it. + +Previously, when those devices reported a temperature of, for example, 67.6F it +would be rounded and reported in whole precision as 68F. Those devices will now +report the temperature with tenth precision, thus 67.6F. + +This means that if you currently have automation that depends on the temperature +reported by these devices you may have to adjust their functionality to work +properly with how the temperature is now being reported. + +([@chilicheech] - [#48133]) ([zwave_js docs]) + +The event names for Z-Wave JS value notification (central scene) events will +now be called `zwave_js_value_notification` and notification (e.g., +locking or unlocking a lock) events will now be called `zwave_js_notification`. + +For notification events, the properties that Z-Wave JS provides have changed, +and we have changed the HA event property names to reflect that. The parameter +that used to be called `label` (The human-readable label for the +notification **event**) is now called `event_label` as there is now a +new `label` property which is the human-readable label for the notification +**type**. + +In addition, we now support notification events for two command classes, Entry +Control and Notification, so the command class is reflected in the event data. +You can learn more about the different command class notifications and what each +parameter means for the different notifications here: + + + +([@raman325] - [#48094]) ([zwave_js docs]) + +{% enddetails %} + +{% details "Templates" %} + +Previously, during template rendering, undefined variables are replaced with an +empty string. As an example the template `{{undefined_variable}}` will render as +the empty string. This is error prone as it means misspelled or non existent +variables are silently accepted by the template engine. + +Starting this release, there will be a warning message in the log when a +variable is undefined, but it is still rendered as the empty string. So, besides +the warning, right now, nothing changes. + +Starting with Home Assistant 2021.10, undefined variables will be treated as an +error and template rendering will fail. + +To allow rendering of templates where it is expected that a variably may not +be defined without logging a warning or failing to render, use the `default` +filter: `{{undefined_variable | default}}`. + +([@emontnemery] - [#48140]) + +{% enddetails %} + +{% details "ZeroConf" %} + +Zeroconf will now only listen on the default interface by default. + +If you need to broadcast mDNS responses to all interfaces or retain the +previous behavior, set [default_interface](/integrations/zeroconf/#default_interface) +to `false`. + +With multiple interfaces, mDNS traffic processing happened numerous times since +the duplicate packets appeared on each interface. This behavior was not +desirable for most cases which necessitated a change in the default. + +The Home Assistant Operating System has multiple interfaces and was affected. + +([@bdraco] - [#48302]) ([zeroconf docs]) + +{% enddetails %} + +{% details "Google Cast" %} + +The YAML configuration for the Google Cast integration has been deprecated and +will be fully removed in Home Assistant Core 2021.6.0. + +If you have existing YAML configuration for the Google Cast integration, please +remove it from your configuration. + +([@emontnemery] - [#47269]) ([cast docs]) + +{% enddetails %} + +{% details "Neato" %} + +Vacuum attributes `clean start`, `clean stop` and camera +attribute `generated_at` are now in a timestamp format. + +New format is "2021-03-20T10:35:47Z". This allow automation to use their +value based on `as_timestamp()`. + +If you relies on these attributes in your automation or script, you might need +to adjust them to match this change. + +([@chemelli74] - [#48150]) ([neato docs]) + +{% enddetails %} + +{% details "MQTT" %} + +The [fan entity model](https://developers.home-assistant.io/docs/core/entity/fan/) +has been changed. This impacts the way the MQTT Fan supports speeds and the +following configuration options are deprecated and will be removed in +Home Assistant Core 2021.7.0: + +- `speed_command_topic` +- `speed_state_topic` +- `state_value_template` +- `speed_list` + +Additionally,`preset_modes` and `percentage` are added to replace the legacy +model supporting only three speeds `low`, `medium` and `high`. +Therefore, `command templates` for `state`, `oscillation`, `preset_mode` and +`percentage` are introduced. + +([@jbouwh] - [#47944] [#48413]) ([mqtt docs]) + +{% enddetails %} + +{% details "Core / Custom integrations" %} + +Block detectable I/O in the event loop + +We added a warning when this happens last April and gave developers +a year to fix the instability. We now prevent the instability by +raising RuntimeError when code attempts to do known I/O in the +event loop instead of the executor. + +We now provide a suggestion on how to fix the code that is causing +the issue. + +([@bdraco] - [#48387]) + +{% enddetails %} + +{% details "ModBus" %} + +You can now use the new style configuration when configuring the modbus +integration. The existing configuration style is kept, allowing you to change +gradually. + +Remark the existing configuration style will be removed in a couple of releases. + +Example of an existing configuration: + +```yaml +modbus: + - name: "hub1" + type: tcp + host: IP_ADDRESS + port: 502 + +sensor: + platform: modbus + registers: + - name: "Sensor1" + hub: "hub1" + unit_of_measurement: "°C" + slave: 1 + register: 100 +``` + +Same configuration in new style: + +```yaml +modbus: + - name: "hub1" + type: tcp + host: IP_ADDRESS + port: 502 + sensors: + - name: "Sensor1" + slave: 1 + address: 100 +``` + +([@janiversen] - [#46591]) ([modbus docs]) + +{% enddetails %} + +{% details "Updater" %} + +The `reporting` and `include_used_components` configuration options have now +been deprecated, the `updater` integration will no longer report any analytics. + +The analytics has moved to it's own integration. +See the [`analytics` integration](/integrations/analytics) for more details on +how to configure it. + +([@ludeeus] - [#48518]) ([updater docs]) + +{% enddetails %} + +{% details "SolarEdge" %} + +The SolarEdge configuration via YAML has been deprecated and will be removed in +a future release of Home Assistant. The integration is using a configuration via +the UI for two years now. + +Existing YAML configurations are automatically imported into the UI, and can be +safely removed from your YAML configuration. + +([@frenck] - [#48533]) ([solaredge docs]) + +{% enddetails %} + +{% details "SolarEdge" %} + +MQTT JSON light now supports `color_mode` which should be used together with +`supported_color_modes` to signal the light's features. + +Feature flags `color_temp`, `hs`, `rgb`, `white_value`, `xy` are all deprecated +and support will be removed in 2021.10. + +([@emontnemery] - [#47993]) ([mqtt docs]) + +{% enddetails %} + +{% details "Ping" %} + +When restarting Home Assistant, the previous ping sensor state is now +restored and then updated in the background to allow startup to proceed +without the risk of timing out. + +When the user has many ping sensors, the ping integration could +timeout starting up because each ping has to happen in the +executor. + +([@bdraco] - [#43869]) ([ping docs]) + +{% enddetails %} + +## Farewell to the following + +The following integrations are no longer available as of this release: + +- **Griddy** has been removed, Ercot shut down Griddy after the massive power + mess in Texas in mid February. ([@bdraco] - [#47218]) + +## All changes + +{% details "Click to see all changes!" %} + +- Bump version to 2021.4.0dev0 ([@frenck] - [#47017]) +- Convert discovery helper to use dispatcher ([@balloob] - [#47008]) ([discovery docs]) ([octoprint docs]) +- Upgrade TwitterAPI to 2.6.8 ([@fabaff] - [#47019]) ([twitter docs]) +- Add Xiaomi Miio fan config flow ([@starkillerOG] - [#46866]) ([xiaomi_miio docs]) (breaking-change) +- hm climate: Return PRESET_NONE instead of None ([@FHeilmann] - [#47003]) ([homematic docs]) +- Normally there should only be one battery sensor per device from deCONZ. ([@Kane610] - [#46761]) ([deconz docs]) +- Upgrade icmplib to 2.0.2 ([@fabaff] - [#47039]) ([ping docs]) +- Clean up discovery integration ([@balloob] - [#47022]) ([daikin docs]) ([discovery docs]) ([freebox docs]) +- Upgrade pyowm to 3.2.0 ([@fabaff] - [#47042]) ([openweathermap docs]) +- Upgrade sendgrid to 6.6.0 ([@fabaff] - [#47041]) ([sendgrid docs]) +- Add remote control platform to Panasonic Viera ([@joogps] - [#42450]) ([panasonic_viera docs]) (new-platform) +- Bump gios library to version 0.2.0 ([@bieniu] - [#47050]) ([gios docs]) +- Replace wrong domain returned from xbox api 2.0 ([@Melantrix] - [#47021]) ([xbox docs]) +- Add zeroconf discovery to Freebox ([@Quentame] - [#47045]) ([discovery docs]) ([freebox docs]) +- Clean up Netatmo webhook handler ([@cgtobi] - [#47037]) ([netatmo docs]) +- Fix bond typing in config flow ([@bdraco] - [#47055]) ([bond docs]) +- Fix Z-Wave JS API docstrings ([@cgarwood] - [#47061]) ([zwave_js docs]) +- Upgrade youtube_dl to version 2021.02.22 ([@chpego] - [#47078]) ([media_extractor docs]) +- Bump pychromecast to 9.0.0 ([@emontnemery] - [#47086]) ([cast docs]) +- Remove flaky climacell test ([@raman325] - [#47080]) ([climacell docs]) +- Add suggested_area support to devolo Home Control ([@Shutgun] - [#47063]) ([devolo_home_control docs]) +- Guard zwave_js missing nodes in websocket api ([@cgarwood] - [#47096]) ([zwave_js docs]) +- Improve handling for recording start of nest cam stream ([@allenporter] - [#47144]) ([stream docs]) +- Change device class of window covers to shade ([@Kane610] - [#47129]) ([deconz docs]) +- Bump airly library to version 1.1.0 ([@bieniu] - [#47163]) ([airly docs]) +- Clean up mqtt_room ([@tkdrob] - [#46882]) ([mqtt_room docs]) +- Tweak Tasmota fan typing ([@emontnemery] - [#47175]) ([tasmota docs]) +- Apply recommendations to synology_dsm ([@mib1185] - [#47178]) ([synology_dsm docs]) +- Fix flaky hls keepalive test ([@allenporter] - [#47186]) ([stream docs]) +- Remove turn_on and turn_off from SmartTub pump switches ([@mdz] - [#47184]) ([smarttub docs]) +- Move SmartTub climate constants to module level ([@mdz] - [#47190]) ([smarttub docs]) +- Explain why should_pool is True initially for wemo ([@esev] - [#47191]) ([wemo docs]) +- Cleanup SmartTub filtration cycles ([@mdz] - [#47192]) ([smarttub docs]) +- Handle stream failures in recorder ([@allenporter] - [#47151]) ([stream docs]) +- Enforce typing in bond ([@bdraco] - [#47187]) ([bond docs]) +- Update pylint ([@cdce8p] - [#47205]) +- Add hassio addon_update service and hassio config entry with addon and OS devices and entities ([@raman325] - [#46342]) ([hassio docs]) (new-platform) +- Improve CI workflow ([@cdce8p] - [#46696]) +- Revert const replacement in fritzbox_callmonitor ([@cgtobi] - [#47211]) ([fritzbox_callmonitor docs]) +- Remove griddy integration ([@bdraco] - [#47218]) ([griddy docs]) +- KNX services send and event_register accept multiple group addresses ([@farmio] - [#46908]) ([knx docs]) +- Deprecate knx config_file ([@farmio] - [#46874]) ([knx docs]) (breaking-change) +- Restore pylint concurrency ([@frenck] - [#47221]) +- Parameterize SmartTub tests ([@mdz] - [#47189]) ([smarttub docs]) +- Upgrade coverage to 5.5 ([@frenck] - [#47227]) +- Upgrade spotipy to 2.17.1 ([@frenck] - [#47228]) ([spotify docs]) +- Bump mcstatus to 5.1.1 ([@jdeath] - [#47169]) ([minecraft_server docs]) +- Overhaul command_line tests ([@dermotduffy] - [#46682]) ([command_line docs]) +- Minor Hyperion mypy cleanups ([@dermotduffy] - [#45765]) ([hyperion docs]) +- Address late hassio review ([@raman325] - [#47229]) ([hassio docs]) +- KNX address constant ([@farmio] - [#47196]) ([knx docs]) +- Add support for a list of known hosts to Google Cast ([@emontnemery] - [#47232]) ([cast docs]) +- Add remote control support to philips_js ([@elupus] - [#47249]) ([philips_js docs]) (new-platform) +- Deprecate LIFX Legacy integration ([@frenck] - [#47235]) ([lifx_legacy docs]) (breaking-change) +- Fix typo in plaato strings ([@milanmeu] - [#47245]) ([plaato docs]) +- Remove rounding from The Things Network ([@stephan192] - [#47157]) ([thethingsnetwork docs]) +- Add battery sensor for gogogate2 wireless door sensor ([@emontnemery] - [#47145]) ([gogogate2 docs]) (new-platform) +- Fix typing on fan percentage ([@bdraco] - [#47259]) +- Lint suppression cleanups ([@scop] - [#47248]) +- Clean up constants ([@tkdrob] - [#46948]) +- Add init test to Freebox ([@Quentame] - [#46998]) ([freebox docs]) +- Add services for izone airflow min/max ([@Nick-Adams-AU] - [#45727]) ([izone docs]) +- Fix izone flake8 error ([@frenck] - [#47276]) ([izone docs]) +- Add force_update to tasmota sensors ([@rlehfeld] - [#47052]) ([tasmota docs]) +- Upgrade isort to 5.7.0 ([@scop] - [#47279]) +- Add disk sensor to Freebox ([@Quentame] - [#46689]) ([freebox docs]) +- Uniformize platform setup ([@Quentame] - [#47101]) +- Clean up secret loading ([@balloob] - [#47034]) (breaking-change) +- KNX remove custom deprecation warnings ([@farmio] - [#47238]) ([knx docs]) +- Add activity properties to remote entity model ([@bdraco] - [#47237]) ([harmony docs]) ([remote docs]) +- bump python-smarttub to 0.0.19 ([@mdz] - [#47294]) ([smarttub docs]) +- Remove name from keenetic-ndms2 strings ([@milanmeu] - [#47113]) ([keenetic_ndms2 docs]) +- Correct gogogate2 battery sensor attributes ([@emontnemery] - [#47302]) ([gogogate2 docs]) +- Update izone services.yaml and remove entity_id from schema. ([@Nick-Adams-AU] - [#47305]) ([izone docs]) +- Fix Supervisor platform coordinator data lookup ([@MartinHjelmare] - [#47308]) ([hassio docs]) +- Philips JS correct post review comments ([@elupus] - [#47247]) ([philips_js docs]) +- Fix grammar in pi_hole logs ([@tkdrob] - [#47324]) ([pi_hole docs]) +- Add LZW36 device schema to zwave_js discovery ([@firstof9] - [#47314]) ([zwave_js docs]) +- Initial automation tracing ([@emontnemery] - [#46755]) ([automation docs]) ([config docs]) ([script docs]) +- Fix secrets in files included via include_dir_list ([@frenck] - [#47350]) +- Update Solax library to 0.2.6 ([@ppetru] - [#47384]) ([solax docs]) +- Update browse_media.py ([@cgtobi] - [#47414]) ([xbox docs]) +- Fix typo in docs link for forked_daapd ([@Cooper-Dale] - [#47413]) ([forked_daapd docs]) +- Spellcheck on Synology component ([@systemcrash] - [#47451]) ([synology_dsm docs]) +- Add allenporter to stream codeowners ([@uvjustin] - [#47431]) ([stream docs]) +- Limit log spam by ESPHome ([@amelchio] - [#47456]) ([esphome docs]) +- Clean up constants ([@tkdrob] - [#47323]) +- Prevent Zerproc leaving open unnecessary connections ([@emlove] - [#47401]) ([zerproc docs]) +- Deprecate HomeKit auto start ([@frenck] - [#47470]) ([homekit docs]) (breaking-change) +- Convert kulersky to use new async backend ([@emlove] - [#47403]) ([kulersky docs]) +- Increase test coverage of UniFi integration ([@Kane610] - [#46347]) ([unifi docs]) +- Typing tweak to the Elgato integration ([@frenck] - [#47471]) ([elgato docs]) +- Improve restoring UniFi POE entity state ([@Kane610] - [#47148]) ([unifi docs]) +- Update ZHA dependencies ([@Adminiuga] - [#47479]) ([zha docs]) +- Move AsusWrt sensors update logic in router module ([@ollo69] - [#46606]) ([asuswrt docs]) +- Complete typing on TwenteMilieu integration ([@frenck] - [#47480]) ([twentemilieu docs]) +- Complete typing on Verisure integration ([@frenck] - [#47482]) ([verisure docs]) +- Add OPENING & CLOSING state to MySensors cover ([@FidgetyRat] - [#47285]) ([mysensors docs]) +- Upgrade upcloud-api to 1.0.1 ([@scop] - [#47501]) ([upcloud docs]) +- Merge action and condition traces ([@emontnemery] - [#47373]) ([automation docs]) +- Disable audio stream when ADTS AAC detected ([@uvjustin] - [#47441]) ([stream docs]) +- Complete typing on AdGuard Home integration ([@frenck] - [#47477]) ([adguard docs]) +- Add precipitation probability forecast to owm ([@N1c093] - [#47284]) ([openweathermap docs]) +- Add device classes for CO and CO2 measurements ([@Adminiuga] - [#47487]) ([sensor docs]) +- Change default homekit ports to 21063 and 21064 ([@bdraco] - [#47491]) ([homekit docs]) +- Increase ESPHome log level on first connection failure ([@amelchio] - [#47547]) ([esphome docs]) +- Improve common structure in UniFi device tracker tests ([@Kane610] - [#47526]) ([unifi docs]) +- Correctly close lacrosse on homeassistant stop ([@jplitza] - [#47555]) ([lacrosse docs]) +- Clean up Lutron Caseta ([@tkdrob] - [#47534]) ([lutron_caseta docs]) +- Clean up kmtronic ([@tkdrob] - [#47537]) ([kmtronic docs]) +- Round miles in myChevy sensors ([@austinmroczek] - [#46879]) ([mychevy docs]) +- Remove @newAM from hdmi_cec codeowners ([@newAM] - [#47542]) ([hdmi_cec docs]) +- Bump actions/stale from v3.0.17 to v3.0.18 (@dependabot - [#47612]) +- Update rokuecp to 0.8.1 ([@ctalkington] - [#47589]) ([roku docs]) +- Upgrade elgato to 2.0.1 ([@frenck] - [#47616]) ([elgato docs]) +- Upgrade pre-commit to 2.11.0 ([@frenck] - [#47618]) +- Add support for Flo "pucks" ([@adamjernst] - [#47074]) ([flo docs]) +- Allow 10mV precision for ZHA battery sensor entities ([@Adminiuga] - [#47520]) ([zha docs]) +- Add feels like temperature sensor to OpenWeatherMap ([@freekode] - [#47559]) ([openweathermap docs]) +- Code cleanup for SmartTub integration ([@mdz] - [#47584]) ([smarttub docs]) +- Upgrade pillow to 8.1.2 ([@frenck] - [#47619]) +- Add (some) of ZCL concentration clusters to ZHA component ([@B-Hartley] - [#47590]) ([zha docs]) +- Store automation traces indexed by run_id ([@emontnemery] - [#47509]) ([automation docs]) +- Add title key to allow mobile app title translation to other languages ([@Antoni-Czaplicki] - [#46593]) ([mobile_app docs]) +- Add suggested_area support to Apple TV ([@bdraco] - [#47015]) ([apple_tv docs]) +- Remove self as code owner for mylink ([@bdraco] - [#46242]) ([somfy_mylink docs]) +- Config flow to allow marking itself as confirm only ([@balloob] - [#47607]) +- Fix I-frame interval in stream test video ([@uvjustin] - [#47638]) +- Add WS command to get a summary of automation traces ([@emontnemery] - [#47557]) ([automation docs]) ([config docs]) +- Add type hints to LightEntity ([@thecode] - [#47024]) ([light docs]) +- Ensure bond light follows proper typing ([@spacegaier] - [#47641]) ([bond docs]) +- Include changed variables in automation trace ([@emontnemery] - [#47549]) +- Update attrs to 20.3.0 ([@scarface-4711] - [#47642]) +- Add option to reverse switch behaviour in KMTronic ([@dgomes] - [#47532]) ([kmtronic docs]) +- Upgrade sentry-sdk to 1.0.0 ([@frenck] - [#47626]) ([sentry docs]) +- Upgrade aiohttp to 3.7.4.post0 ([@frenck] - [#47627]) +- Fix maxcube thermostat transition from off to heat mode ([@unaiur] - [#47643]) ([maxcube docs]) +- Catch dhcp setup permission errors sooner ([@bdraco] - [#47639]) ([dhcp docs]) +- Harmony: set confirm only ([@bdraco] - [#47617]) ([harmony docs]) +- Add error message to options flow if connection fails for nut integration ([@mib1185] - [#46972]) ([nut docs]) +- Shelly: set confirm only ([@balloob] - [#47608]) ([shelly docs]) +- Revert Shelly temperature sensor name change ([@thecode] - [#47664]) ([shelly docs]) +- Replace Entity.device_state_attributes with Entity.extra_state_attributes ([@emontnemery] - [#47304]) +- Update tests a-b to use async_get() instead of async_get_registry() ([@emontnemery] - [#47651]) +- Update tests t-z to use async_get() instead of async_get_registry() ([@emontnemery] - [#47655]) +- Update tests p-s to use async_get() instead of async_get_registry() ([@emontnemery] - [#47654]) +- Update tests c-h to use registry async_get ([@emontnemery] - [#47652]) +- Update tests i-o to use async_get() instead of async_get_registry() ([@emontnemery] - [#47653]) +- Add TYPE_CHECKING to coverage excludes ([@cdce8p] - [#47668]) +- Rename AutomationTrace.runid to AutomationTrace.run_id ([@emontnemery] - [#47669]) ([automation docs]) +- Improve logging elgato ([@balloob] - [#47681]) ([elgato docs]) +- Handle zeroconf updated events ([@balloob] - [#47683]) ([zeroconf docs]) +- Fix recorder with MSSQL ([@bdraco] - [#46678]) ([recorder docs]) +- Restore switch.turn_on and switch.turn_off functionality for SmartTub pumps ([@mdz] - [#47586]) ([smarttub docs]) +- Add confirm only for Elgato ([@frenck] - [#47684]) ([elgato docs]) +- Use the local timezone when parsing Todoist due dates ([@c99koder] - [#45994]) ([todoist docs]) +- Add support for breakpoints in scripts ([@emontnemery] - [#47632]) ([automation docs]) ([config docs]) +- Fix automations with traces. ([@balloob] - [#47705]) ([automation docs]) +- Bump codecov/codecov-action from v1.2.1 to v1.2.2 (@dependabot - [#47707]) +- Fix aemet temperatures with a value of 0 ([@Noltari] - [#47680]) ([aemet docs]) +- Add device class CO2 to various integrations ([@iMicknl] - [#47676]) ([ambient_station docs]) ([awair docs]) ([fibaro docs]) ([netatmo docs]) ([tasmota docs]) +- bump client library ([@zxdavb] - [#47722]) ([evohome docs]) +- Bump incomfort client to 0.4.4 ([@zxdavb] - [#47718]) ([incomfort docs]) +- Use LONGTEXT column instead of TEXT for MySQL/MariaDB and migrate existing databases ([@CurrentThread] - [#47026]) ([recorder docs]) +- Refactor Harmony tests to better follow Home Assistant conventions ([@mkeesey] - [#47141]) ([harmony docs]) +- Allow SSDP discovery modern Hue hubs ([@balloob] - [#47725]) ([hue docs]) +- Improve HomeKit discovered Hue config flow ([@frenck] - [#47729]) ([hue docs]) +- Add Tado weather support ([@Noltari] - [#44807]) ([tado docs]) (new-platform) +- Update xknx to 0.17.2 ([@farmio] - [#47732]) ([knx docs]) +- Add missing clear-night weather condition ([@hung2kgithub] - [#47666]) ([template docs]) +- Tweak automation tracing ([@emontnemery] - [#47721]) ([automation docs]) ([config docs]) +- Verify get_zones webhook works ([@balloob] - [#47741]) ([mobile_app docs]) +- Ensure startup can proceed when there is package metadata cruft ([@bdraco] - [#47706]) +- Fixed string typos in Lutron and Roomba ([@spacegaier] - [#47745]) ([lutron_caseta docs]) ([roomba docs]) +- Fix light brightness_step on multiple entities ([@emontnemery] - [#47746]) ([light docs]) +- Add Xiaomi Miio sensor config flow ([@starkillerOG] - [#46964]) ([xiaomi_miio docs]) (breaking-change) +- Hoist mqtt name property and add icon support to MqttEntity ([@kristianheljas] - [#47165]) ([mqtt docs]) +- Add Xiaomi Miio light config flow ([@starkillerOG] - [#47161]) ([xiaomi_miio docs]) (breaking-change) +- Update integrations a-e to override extra_state_attributes() ([@emontnemery] - [#47756]) +- Update integrations f-i to override extra_state_attributes() ([@emontnemery] - [#47757]) +- Recorder improvements ([@cdce8p] - [#47739]) ([recorder docs]) +- Add DataUpdateCoordinator to Verisure ([@frenck] - [#47574]) ([verisure docs]) +- Update integrations j-o to override extra_state_attributes() ([@emontnemery] - [#47758]) +- Update integrations t-z to override extra_state_attributes() ([@emontnemery] - [#47760]) +- Update integrations p-s to override extra_state_attributes() ([@emontnemery] - [#47759]) +- Consistent spelling of "PIN" ([@spacegaier] - [#47771]) ([blink docs]) ([ecobee docs]) ([hangouts docs]) ([nest docs]) ([zwave docs]) +- Upgrade numato-gpio to 0.10.0 ([@clssn] - [#47539]) ([numato docs]) +- Upgrade adguardhome to v0.5.0 ([@frenck] - [#47774]) ([adguard docs]) +- Add apply_filter attribute to recorder.purge service ([@cdce8p] - [#45826]) ([recorder docs]) +- Bump broadlink from 0.16.0 to 0.17.0 ([@felipediel] - [#47779]) ([broadlink docs]) +- Bump pyIntesisHome to v1.7.6 ([@jnimmo] - [#47500]) ([intesishome docs]) +- Log the full exception when the recorder fails to setup ([@bdraco] - [#47770]) ([recorder docs]) +- Cleanup homekit and remove aid storage from hass.data ([@bdraco] - [#47488]) ([homekit docs]) +- Improve Atag integration and bump version to 0.3.5.3 ([@MatsNl] - [#47778]) ([atag docs]) +- Store the correct context in the trace ([@balloob] - [#47785]) ([automation docs]) +- Do not use AsyncTrackStates ([@balloob] - [#47255]) ([api docs]) +- Bump devolo_home_control_api to 0.17.0 ([@Shutgun] - [#47790]) ([devolo_home_control docs]) +- Remove unused COVER_SCHEMA from gogogate2 cover ([@emontnemery] - [#47170]) ([gogogate2 docs]) +- Bump pyatv to 0.7.7 ([@postlund] - [#47798]) ([apple_tv docs]) +- Allow filtering the logbook by context_id ([@balloob] - [#47783]) ([logbook docs]) +- Add ambient sensors to nut integration ([@mib1185] - [#47411]) ([nut docs]) +- Add temperature sensor for gogogate2 wireless door sensor ([@emontnemery] - [#47754]) ([gogogate2 docs]) +- Return property_key in zwave_js get_config_parameters websocket ([@cgarwood] - [#47808]) ([zwave_js docs]) +- Add HomeKit support for new CO / CO2 device class ([@iMicknl] - [#47737]) ([demo docs]) ([homekit docs]) +- UniFi has changed to not report uptime in epoch form ([@Kane610] - [#47492]) ([unifi docs]) +- Improve deCONZ init tests ([@Kane610] - [#47825]) ([deconz docs]) +- Introduction of deCONZ websocket fixture ([@Kane610] - [#47812]) ([deconz docs]) +- Update cloud integration to 0.42.0 ([@klaasnicolaas] - [#47818]) ([cloud docs]) +- Additional sensors for OpenWeatherMap ([@hanskroner] - [#47806]) ([openweathermap docs]) +- Fix unclean shutdown of recorder test ([@emontnemery] - [#47791]) ([recorder docs]) +- fix exception on device removal ([@dmulcahey] - [#47803]) ([zha docs]) +- Bump frontend to 20210313.0 ([@balloob] - [#47844]) ([frontend docs]) +- Fix missing integer cast in squeezebox config flow ([@rajlaud] - [#47846]) ([squeezebox docs]) +- Add timeouts in stream tests to prevent possible hangs ([@allenporter] - [#47545]) ([stream docs]) +- Fix zwave_js preset supported feature ([@raman325] - [#47819]) ([zwave_js docs]) +- Fix spelling of automatically in roomba/lutron_caseta components ([@tdorsey] - [#47856]) ([lutron_caseta docs]) ([roomba docs]) +- Update aiolyric to v1.0.6 ([@timmo001] - [#47871]) ([lyric docs]) +- Add device_info to Apple TV entities ([@postlund] - [#47837]) ([apple_tv docs]) +- Bump up ZHA dependency ([@Adminiuga] - [#47873]) ([zha docs]) +- Fix zwave_js preset mode lookup ([@MartinHjelmare] - [#47851]) ([zwave_js docs]) +- Update service config for lyric ([@timmo001] - [#47857]) ([lyric docs]) +- Add HVAC action to Lyric climate platform ([@timmo001] - [#47876]) ([lyric docs]) +- Verisure: Remove JSONPath, unique IDs, small cleanups ([@frenck] - [#47870]) ([verisure docs]) +- Add Xiaomi Miio subdevice lightbulb support ([@starkillerOG] - [#46660]) ([xiaomi_miio docs]) +- Upgrade Tibber library to 0.16.2 ([@Danielhiversen] - [#47892]) ([tibber docs]) +- Reduce number of iqair request ([@jugla] - [#47890]) ([airvisual docs]) +- Update pyhomematic to 0.1.72 ([@danielperna84] - [#47906]) ([homematic docs]) +- Improve error reporting in recorder purge test ([@bdraco] - [#47929]) ([recorder docs]) +- Fix homekit checking for port cleanup too many times ([@bdraco] - [#47836]) ([homekit docs]) +- Add suggested area support to august ([@bdraco] - [#47930]) ([august docs]) +- Bump accuweather library ([@bieniu] - [#47915]) ([accuweather docs]) +- Bump gios library ([@bieniu] - [#47917]) ([gios docs]) +- Upgrade to maxcube-api-0.4.1 ([@unaiur] - [#47910]) ([maxcube docs]) +- Invalidate HLS Stream on nest url refresh failure ([@allenporter] - [#47869]) ([nest docs]) +- Address review comments and minor fix for Mazda integration ([@bdr99] - [#47702]) ([mazda docs]) +- Update openwrt-luci-rpc from 1.1.6 to 1.1.8 ([@pdecat] - [#47848]) ([luci docs]) +- Improve bad JSON data reporting ([@balloob] - [#47932]) +- MQTT Light: Use flash attribute in async_turn_off ([@drzony] - [#47919]) ([mqtt docs]) +- Support all Xiaomi Miio gateway switches ([@starkillerOG] - [#46657]) ([xiaomi_miio docs]) +- Make Xiaomi Miio unavailable device independent ([@starkillerOG] - [#47795]) ([xiaomi_miio docs]) +- Add Hive config flow ([@KJonline] - [#47300]) ([hive docs]) (breaking-change) +- Add tests for Netatmo climate ([@cgtobi] - [#46392]) ([netatmo docs]) +- Upgrade qnapstats library to 0.3.1 ([@colinodell] - [#47907]) ([qnap docs]) +- Clean up Lyric ([@timmo001] - [#47899]) ([lyric docs]) +- Migrate LCN configuration to ConfigEntry (Part 1) ([@alengwenus] - [#44090]) ([lcn docs]) +- Upgrade vsure to 1.7.3 ([@frenck] - [#47946]) ([verisure docs]) +- Sort supported features in vlc_telnet ([@dmcc] - [#46800]) ([vlc_telnet docs]) +- Add zwave_js dev docs readme ([@MartinHjelmare] - [#47621]) ([zwave_js docs]) +- None optional hass typing in base entity and notify ([@frenck] - [#47528]) +- Bump brother library ([@bieniu] - [#47949]) ([brother docs]) +- Implement Wake On Lan Dummy State ([@ntilley905] - [#47719]) ([wake_on_lan docs]) (breaking-change) +- Update state translation strings for water_heater ([@iMicknl] - [#46588]) ([water_heater docs]) +- Ensure recorder purge tests can handle multiple purge cycle ([@bdraco] - [#47956]) ([recorder docs]) +- Use ClientTimeout for hassio send_command ([@ludeeus] - [#47957]) ([hassio docs]) +- improve debug logging ([@mib1185] - [#47858]) ([synology_dsm docs]) +- Add suggested_area to MQTT discovery ([@RadekHvizdos] - [#47903]) ([mqtt docs]) +- Add config flow to Verisure ([@frenck] - [#47880]) ([verisure docs]) (breaking-change) +- Add zwave_js sensor humidity device class ([@MartinHjelmare] - [#47953]) ([zwave_js docs]) +- Move Verisure services to entity services ([@frenck] - [#47905]) ([verisure docs]) (breaking-change) +- Add devices to Verisure integration ([@frenck] - [#47913]) ([verisure docs]) +- Make it possible to list debug traces for a specific automation ([@emontnemery] - [#47744]) ([automation docs]) +- Fix xmpp notify for muc rooms ([@Socalix] - [#46715]) ([xmpp docs]) +- Add voltage device class to devolo Home Control ([@Shutgun] - [#47967]) ([devolo_home_control docs]) +- Add reauthentication to Verisure ([@frenck] - [#47972]) ([verisure docs]) +- Correct trace for choose and repeat script actions ([@emontnemery] - [#47973]) +- Add execute_script WS API ([@emontnemery] - [#47964]) ([websocket_api docs]) +- Add support for light color modes ([@emontnemery] - [#47720]) ([kulersky docs]) ([light docs]) ([yeelight docs]) ([zerproc docs]) +- Add custom JSONEncoder for automation traces ([@emontnemery] - [#47942]) ([automation docs]) +- Guard extra call in ZHA lights ([@dmulcahey] - [#47832]) ([zha docs]) +- Ignore STATE_UNKNOWN in prometheus ([@inetAnt] - [#47840]) ([prometheus docs]) (breaking-change) +- Add device classes to Verisure sensors ([@frenck] - [#47990]) ([verisure docs]) +- Update xknx to 0.17.3 ([@farmio] - [#47996]) ([knx docs]) +- Improve JSONEncoder test coverage ([@emontnemery] - [#47935]) +- Add aliases to actions in automation blueprints ([@klaasnicolaas] - [#47940]) ([automation docs]) +- Fix withings InvalidParamsException ([@ronaldheft] - [#47975]) ([withings docs]) +- Bump up ZHA dependencies ([@Adminiuga] - [#47997]) ([zha docs]) +- Add binary_sensor entities for SmartTub reminders ([@mdz] - [#47583]) ([smarttub docs]) +- Add support for Xiaomi Air Purifier Pro H ([@billsq] - [#47601]) ([xiaomi_miio docs]) +- Add missing "pin" field in step "pair" for philips_js ([@eifinger] - [#47802]) ([philips_js docs]) +- Upgrade youtube_dl to version 2021.03.14 ([@chpego] - [#48000]) ([media_extractor docs]) +- Add location details to deprecation warning ([@alandtse] - [#47155]) +- KNX sensor: float no longer valid for `type` ([@farmio] - [#48005]) ([knx docs]) (breaking-change) +- Add run_id to automation logbook event ([@balloob] - [#47980]) ([automation docs]) +- Delay ZHA group updates to ensure all members are updated first ([@abmantis] - [#46861]) ([zha docs]) +- Remove YAML support from August ([@bdraco] - [#47615]) ([august docs]) (breaking-change) +- Add Pentair ScreenLogic integration ([@dieselrabbit] - [#47933]) ([screenlogic docs]) (new-integration) +- Fix historic attributes for input_datetime ([@spacegaier] - [#45208]) ([history docs]) +- Fix issue with setting sleep mode during DST ([@natekspencer] - [#48001]) ([litterrobot docs]) +- Add support for percentage based fan model in esphome ([@blejdfist] - [#46712]) ([esphome docs]) +- Bump codecov/codecov-action from v1.2.2 to v1.3.1 (@dependabot - [#48020]) +- Add Logger Check Before Adding Another ([@ntilley905] - [#47954]) +- Rewrite tests for Template Light ([@sycx2] - [#41163]) ([template docs]) +- Update metadata license string ([@cdce8p] - [#46899]) +- Fix workday sensor to honor timezone ([@schiermi] - [#47927]) ([workday docs]) (breaking-change) +- Switch history tests to pytest ([@mdonoughe] - [#42318]) ([history docs]) +- Update typing 01 ([@cdce8p] - [#48013]) +- Improve OWM Precipitation sensors ([@hanskroner] - [#47945]) ([openweathermap docs]) +- Update typing 02 ([@cdce8p] - [#48014]) +- Update typing 03 ([@cdce8p] - [#48015]) +- Add service schema for ESPHome api services ([@glmnet] - [#47426]) ([esphome docs]) +- Update typing 04 ([@cdce8p] - [#48037]) +- Update typing 05 ([@cdce8p] - [#48038]) +- Update typing 06 ([@cdce8p] - [#48039]) +- Google has deprecated a comma separated list for modes changed it to array ([@KartoffelToby] - [#48029]) ([google_assistant docs]) +- Upgraded aiopylgtv to v0.4.0 ([@corneyl] - [#47014]) ([webostv docs]) +- Add a service to reload config entries that can easily be called though automations ([@bdraco] - [#46762]) ([homeassistant docs]) +- Update typing 07 ([@cdce8p] - [#48057]) +- Update typing 08 ([@cdce8p] - [#48058]) +- Use websocket fixture in deCONZ binary sensor tests ([@Kane610] - [#47820]) ([deconz docs]) +- Reduce rest setup code ([@bdraco] - [#48062]) ([rest docs]) +- Use websocket fixture in deCONZ climate tests ([@Kane610] - [#47821]) ([deconz docs]) +- Update typing 09 ([@cdce8p] - [#48059]) +- Use websocket fixture in deCONZ cover tests ([@Kane610] - [#47822]) ([deconz docs]) +- Use websocket fixture in deCONZ event related tests ([@Kane610] - [#47823]) ([deconz docs]) +- Use websocket fixture in deCONZ fan tests ([@Kane610] - [#47824]) ([deconz docs]) +- Use websocket fixture in deCONZ light tests ([@Kane610] - [#47826]) ([deconz docs]) +- Use websocket fixture in deCONZ lock tests ([@Kane610] - [#47827]) ([deconz docs]) +- Use websocket fixture in deCONZ sensor tests ([@Kane610] - [#47830]) ([deconz docs]) +- Use websocket fixture in deCONZ switch tests ([@Kane610] - [#47831]) ([deconz docs]) +- Improve deCONZ services and scenes tests ([@Kane610] - [#47829]) ([deconz docs]) +- Propagate RFLink 'send_command' event ([@javicalle] - [#43588]) ([rflink docs]) +- Amcrest add support for CrossLineDetection ([@andreas-amlabs] - [#44582]) ([amcrest docs]) +- Update typing 10 ([@cdce8p] - [#48071]) +- Allow hdmi_cec to recover from lost connection to adapter without restart ([@rajlaud] - [#40714]) ([hdmi_cec docs]) +- Update typing 11 ([@cdce8p] - [#48072]) +- Ignore not implemented lg_soundbar source/equaliser. ([@bernimoses] - [#45868]) ([lg_soundbar docs]) +- Update typing 12 ([@cdce8p] - [#48073]) +- Update typing 13 ([@cdce8p] - [#48077]) +- Add tests for Netatmo oauth2 api ([@cgtobi] - [#46375]) ([netatmo docs]) +- Update typing 14 ([@cdce8p] - [#48078]) +- Update typing 15 ([@cdce8p] - [#48079]) +- Add URL input for Prowl ([@elyobelyob] - [#46427]) ([prowl docs]) +- Add definitions for grouping media players ([@klada] - [#41193]) ([media_player docs]) +- Add images support to matrix notify ([@bestlibre] - [#37625]) ([matrix docs]) +- Correct trace for repeat script actions ([@emontnemery] - [#48031]) +- Fix Shelly sleeping device initialization after reconfiguration ([@bieniu] - [#48076]) ([shelly docs]) +- Update typing 16 ([@cdce8p] - [#48087]) +- Add python-typing-update to pre-commit-config ([@cdce8p] - [#48088]) +- Update pyupgrade to v2.10.1 ([@cdce8p] - [#48089]) +- Add Opentherm Gateway current and setpoint precision ([@Martidjen] - [#47484]) ([opentherm_gw docs]) +- Refactor Netatmo test ([@cgtobi] - [#48097]) ([netatmo docs]) +- Type check KNX integration expose ([@farmio] - [#48055]) ([knx docs]) +- Type check KNX integration weather, notify and scene ([@farmio] - [#48051]) ([knx docs]) +- Type check KNX integration light ([@farmio] - [#48053]) ([knx docs]) +- Type check KNX integration binary_sensor, sensor and switch ([@farmio] - [#48050]) ([knx docs]) +- Type check KNX integration factory and schema ([@farmio] - [#48045]) ([knx docs]) +- Use device class voltage in NUT integration ([@bieniu] - [#48096]) ([nut docs]) +- Add tests for Netatmo light ([@cgtobi] - [#46381]) ([netatmo docs]) +- Add tests for Netatmo camera ([@cgtobi] - [#46380]) ([netatmo docs]) +- Add "timestamp" attribute to seventeentrack ([@andreasbrett] - [#47960]) ([seventeentrack docs]) +- Fix Homematic transition function on light devices with multiple channels ([@miccico] - [#45725]) ([homematic docs]) +- Upgrade RPi.GPIO to 0.7.1a4 ([@frenck] - [#48106]) ([bmp280 docs]) ([mcp23017 docs]) ([rpi_gpio docs]) +- Improve test coverage of deCONZ config flow ([@Kane610] - [#48091]) ([deconz docs]) +- Add flake8 comprehensions checks to pre-commit & CI ([@frenck] - [#48111]) +- Add missing oauth2 error abort reason ([@MartinHjelmare] - [#48112]) +- Have pylint warn when user visible log messages do not start with capital letter or end with a period ([@bdraco] - [#48064]) +- Wait for switch startup in generic_thermostat ([@javicalle] - [#45253]) ([generic_thermostat docs]) +- Improve uvc test camera ([@sycx2] - [#41438]) ([uvc docs]) (breaking-change) +- Improve sensor coverage by verifying daylight sensor attributes ([@Kane610] - [#48090]) ([deconz docs]) +- Make Vera should_poll static rather than dynamic ([@pavoni] - [#47854]) ([vera docs]) +- Type check KNX integration fan ([@farmio] - [#48056]) ([knx docs]) +- Type check KNX integration cover ([@farmio] - [#48046]) ([knx docs]) +- Remove defunct test from percentage util ([@frenck] - [#48125]) +- Set zwave_js climate precision to tenths for F ([@chilicheech] - [#48133]) ([zwave_js docs]) (breaking-change) +- Rewrite of not a == b occurances ([@frenck] - [#48132]) +- Update pyvesync to 1.3.1 ([@decompil3d] - [#48128]) ([vesync docs]) +- Add tests for Netatmo webhook handler ([@cgtobi] - [#46396]) ([netatmo docs]) +- Yoda assertion style removed is ([@frenck] - [#48142]) +- Improve test coverage of deconz_device ([@Kane610] - [#48141]) ([deconz docs]) +- Warn on undefined variables in templates ([@emontnemery] - [#48140]) (breaking-change) +- Fix a collection of tests with missing asserts ([@frenck] - [#48127]) ([hassio docs]) ([logger docs]) ([recorder docs]) ([tod docs]) ([universal docs]) +- only block coord removal if it is active ([@dmulcahey] - [#48147]) ([zha docs]) +- Use domain const in config_flow ([@spacegaier] - [#48168]) ([ambiclimate docs]) ([daikin docs]) ([mqtt docs]) ([point docs]) ([tellduslive docs]) ([tradfri docs]) +- ESPHome trigger reconnect immediately when mDNS record received ([@OttoWinter] - [#48129]) ([esphome docs]) +- Update RFLink tests ([@javicalle] - [#48149]) ([rflink docs]) +- Small code styling tweaks for HomeKit ([@frenck] - [#48163]) ([homekit docs]) +- Make Rflink handle set_level command for dimmable devices ([@javicalle] - [#46499]) ([rflink docs]) +- Mark base components' state_attribute @final, rename others to extra_state_attributes ([@emontnemery] - [#48161]) +- ScreenLogic cleanups ([@dieselrabbit] - [#48136]) ([screenlogic docs]) (new-platform) +- Fix typo in homekit strings.json ([@eltociear] - [#48176]) ([homekit docs]) +- Preset support for MOES thermostat valves ([@xonestonex] - [#48178]) ([zha docs]) +- Handle switch state updates from Konnected device ([@heythisisnate] - [#48167]) ([konnected docs]) +- Index config entries by id ([@bdraco] - [#48199]) ([config docs]) +- Update homekit to improve representation of activity based remotes ([@bdraco] - [#47261]) ([homekit docs]) +- Make sure include_ignore=False always works with _async_current_entries ([@bdraco] - [#48196]) +- Fix Kulersky and Zerproc config unloading ([@emlove] - [#47572]) ([kulersky docs]) ([zerproc docs]) +- Improve condition trace tests ([@emontnemery] - [#48152]) +- Test that homeassistant stop and restart do not block WS ([@emontnemery] - [#48081]) ([websocket_api docs]) +- Trigger Plex GDM scans regularly ([@jjlawren] - [#48041]) ([plex docs]) +- Exclude homekit accessories created by the homekit integration from homekit_controller ([@bdraco] - [#48201]) ([homekit_controller docs]) +- Increase config entries test coverage ([@bdraco] - [#48203]) +- Convert august to be push instead of poll ([@bdraco] - [#47544]) ([august docs]) +- Ensure homekit yaml config works when there is an ignored config entry ([@bdraco] - [#48175]) ([homekit docs]) +- Populate trigger variable when manually triggering automation ([@balloob] - [#48202]) ([automation docs]) +- Bump yalexs to 1.1.5 for august ([@bdraco] - [#48205]) ([august docs]) +- Remove vera should_poll ([@pavoni] - [#48209]) ([vera docs]) +- Update aqualogic library to v2.6 ([@swilson] - [#48119]) ([aqualogic docs]) +- Migrate integrations a-c to extend SensorEntity ([@emontnemery] - [#48210]) +- Migrate integrations d-e to extend SensorEntity ([@emontnemery] - [#48211]) +- Bump colorlog to 4.8.0 ([@frenck] - [#48218]) +- Upgrade pre-commit to 2.11.1 ([@frenck] - [#48219]) +- Fix maxcube temperature for thermostat auto mode ([@unaiur] - [#48047]) ([maxcube docs]) +- Improve script tracing ([@emontnemery] - [#48100]) +- Upgrade pyupgrade to v2.11.0 ([@frenck] - [#48220]) ([esphome docs]) ([http docs]) ([wunderground docs]) ([zha docs]) +- Add identification for YAML imports ([@starkillerOG] - [#48162]) ([xiaomi_miio docs]) +- Add jobstate parser to Onvif integration ([@MatsNl] - [#46589]) ([onvif docs]) +- Fix condition extra fields for climate and humidifier ([@spacegaier] - [#48184]) ([climate docs]) ([cover docs]) ([humidifier docs]) +- Add an option to hide selected Hyperion effects ([@dermotduffy] - [#45689]) ([hyperion docs]) +- Refactor tracing: Move trace support to its own integration ([@emontnemery] - [#48224]) ([automation docs]) ([trace docs]) (new-integration) +- Migrate integrations f-h to extend SensorEntity ([@emontnemery] - [#48212]) +- Migrate integrations n-q to extend SensorEntity ([@emontnemery] - [#48214]) +- Migrate integrations t-v to extend SensorEntity ([@emontnemery] - [#48216]) +- Migrate integrations w-z to extend SensorEntity ([@emontnemery] - [#48217]) +- Migrate integrations r-s to extend SensorEntity ([@emontnemery] - [#48215]) +- Migrate integrations i-m to extend SensorEntity ([@emontnemery] - [#48213]) +- Improve Docker and Kubernetes support for KNX ([@plomosits] - [#48065]) ([knx docs]) +- Move SensorEntity last in the inheritance tree ([@emontnemery] - [#48230]) +- Clean up AsusWRT ([@balloob] - [#48012]) ([asuswrt docs]) +- Remove login details before logging stream source ([@uvjustin] - [#45398]) ([stream docs]) +- Bump nanoleaf to 0.1.0, add unique IDs ([@dewet22] - [#48135]) ([nanoleaf docs]) +- Add Blink config migration ([@fronzbot] - [#46671]) ([blink docs]) +- Change nanoleaf name to configured name instead of hostname ([@keis] - [#46407]) ([nanoleaf docs]) +- Add august doorbells to dhcp discovery ([@bdraco] - [#48244]) ([august docs]) +- Add dhcp discovery support to blink ([@bdraco] - [#48243]) ([blink docs]) +- Upgrade pylast to 4.2.0 ([@fabaff] - [#48245]) ([lastfm docs]) +- Increase test coverage of deCONZ device triggers ([@Kane610] - [#48126]) ([deconz docs]) +- Add tests for Netatmo ([@cgtobi] - [#46372]) ([netatmo docs]) +- Use contextlib.suppress where possible ([@frenck] - [#48189]) +- Fix some sensor classes ([@emontnemery] - [#48254]) +- Bump up ZHA dependencies ([@Adminiuga] - [#48257]) ([zha docs]) +- Update issue form to use latest changes ([@frenck] - [#48250]) +- Update pypoint to 2.1.0 ([@fredrike] - [#48223]) ([point docs]) +- datetime must be a string ([@dgomes] - [#47809]) ([buienradar docs]) +- Install requirements.txt while building dev Dockerfile ([@ludeeus] - [#48268]) +- Add proper percentage support to deCONZ fan integration ([@Kane610] - [#48187]) ([deconz docs]) +- Bump plexapi to 4.5.0 ([@jjlawren] - [#48264]) ([plex docs]) +- Refactor tracing: Prepare for tracing of scripts ([@emontnemery] - [#48231]) ([automation docs]) ([trace docs]) +- Google assistant: disconnect user agent when not found in google ([@bramkragten] - [#48233]) ([cloud docs]) ([google_assistant docs]) +- Migrate template to register reload service on async_setup ([@balloob] - [#48273]) ([template docs]) +- Add tests for Netatmo sensor ([@cgtobi] - [#46393]) ([netatmo docs]) +- Improve Plex GDM client connections ([@jjlawren] - [#48272]) ([plex docs]) +- Clean up SmartTub reminders ([@mdz] - [#48033]) ([smarttub docs]) +- Fix Core bug report issue form ([@frenck] - [#48279]) +- Add support for tracing script execution ([@emontnemery] - [#48276]) ([automation docs]) ([script docs]) ([trace docs]) +- Add support for Roomba 980 discovery ([@scyto] - [#47696]) ([roomba docs]) +- Ignore python-typing-update for pre-commit requirements ([@cdce8p] - [#48292]) +- Bump omnilogic to 0.4.3 to fix API certificate issue ([@djtimca] - [#48296]) ([omnilogic docs]) +- Handle range conversions that do not start at 1 ([@bdraco] - [#48298]) +- Determine zwave_js sensor device class during initialization ([@raman325] - [#48304]) ([zwave_js docs]) +- Listen on the default interface by default for zeroconf ([@bdraco] - [#48302]) ([zeroconf docs]) (breaking-change) +- Bump plexapi to 4.5.1 ([@jjlawren] - [#48307]) ([plex docs]) +- Add metrics upload by UDP to graphite ([@BoresXP] - [#43751]) ([graphite docs]) +- Fix missing glances temperature sensors ([@TheNetAdmin] - [#46086]) ([glances docs]) +- Type check KNX integration climate ([@farmio] - [#48054]) ([knx docs]) +- Add allowed UUIDs and ignore CEC to Google Cast options flow ([@emontnemery] - [#47269]) ([cast docs]) (breaking-change) +- Add Homepluscontrol integration ([@chemaaa] - [#46783]) ([homepluscontrol docs]) (new-integration) +- Fix zha manual flow test ([@MartinHjelmare] - [#48317]) ([zha docs]) +- Add econet thermostat support and use getattr for sensors ([@w1ll1am23] - [#45564]) ([econet docs]) (new-integration) (new-platform) +- Fix device discovery of OAuth2 config flows ([@frenck] - [#48326]) +- Add tests for Netatmo data handler ([@cgtobi] - [#46373]) ([netatmo docs]) +- Bump plexwebsocket to 0.0.13 ([@jjlawren] - [#48330]) ([plex docs]) +- Support overriding token in notifify.event service ([@papajojo] - [#47133]) ([notify_events docs]) +- Fix late comment to PR adding percentage support to deCONZ fan platform ([@Kane610] - [#48333]) ([deconz docs]) +- Bump python-typing-update to 0.3.2 ([@cdce8p] - [#48303]) ([deconz docs]) ([yeelight docs]) +- Update in 1 minute on unavailable Motion blinds ([@starkillerOG] - [#47800]) ([motion_blinds docs]) +- Address huisbaasje review comments ([@frenck] - [#48313]) ([huisbaasje docs]) +- Use async with in Acmeda config flow ([@frenck] - [#48291]) ([acmeda docs]) +- Subaru integration code quality changes ([@G-Two] - [#48193]) ([subaru docs]) +- Remove timedate manipulation from Neato attributes ([@chemelli74] - [#48150]) ([neato docs]) (breaking-change) +- xknx 0.17.4 ([@farmio] - [#48350]) ([knx docs]) +- Validate device trigger schemas once ([@emontnemery] - [#48319]) +- Pre-calculate Verisure alarm states ([@frenck] - [#48340]) ([verisure docs]) +- Percentage and preset mode support for MQTT fan ([@jbouwh] - [#47944]) ([homeassistant docs]) ([mqtt docs]) (breaking-change) +- Validate device action schemas once ([@emontnemery] - [#48351]) +- Refactor Netatmo tests ([@cgtobi] - [#48277]) ([netatmo docs]) +- Bump snapcast to 2.1.2 ([@D3v01dZA] - [#48343]) ([snapcast docs]) +- Small speed up to adding entities ([@bdraco] - [#48353]) +- Improve august reconnect logic when service become unreachable ([@bdraco] - [#48349]) ([august docs]) +- Xknx unneeded expose ([@mptei] - [#48311]) ([knx docs]) +- Add Netatmo schedule event handling ([@cgtobi] - [#46573]) ([netatmo docs]) +- Extend typing on scaffold templates ([@frenck] - [#48232]) +- Type check KNX integration __init__ and knx_entity ([@farmio] - [#48044]) ([knx docs]) +- Merge of nested IF-IF cases - X-Z ([@frenck] - [#48373]) ([xiaomi_miio docs]) ([zha docs]) ([zwave docs]) ([zwave_js docs]) +- Create FUNDING.yml ([@balloob] - [#48375]) +- Merge of nested IF-IF case in elkm1 test ([@frenck] - [#48374]) ([elkm1 docs]) +- Improve traces for nested script runs ([@emontnemery] - [#48366]) ([trace docs]) +- Return config entry details after creation ([@emontnemery] - [#48316]) ([config docs]) +- Remove HomeAssistantType alias from AdGuard integration ([@frenck] - [#48377]) ([adguard docs]) +- Fix script default trace ([@balloob] - [#48390]) +- Block detectable I/O in the event loop ([@bdraco] - [#48387]) (breaking-change) +- Bump httpx to 0.17.1 ([@bdraco] - [#48388]) +- Merge multiple context managers in tests ([@frenck] - [#48146]) +- Merge of nested IF-IF cases - Core ([@frenck] - [#48364]) +- Lazy load broadlink storage ([@bdraco] - [#48391]) ([broadlink docs]) +- Merge of nested IF-IF cases - K-N ([@frenck] - [#48370]) +- Upgrade flake8 and dependencies, enable flake8-noqa ([@scop] - [#48393]) ([http docs]) ([seventeentrack docs]) +- Merge of nested IF-IF cases - O-R ([@frenck] - [#48371]) +- Merge of nested IF-IF cases - S-W ([@frenck] - [#48372]) +- Merge of nested IF-IF cases - A-C ([@frenck] - [#48365]) ([agent_dvr docs]) ([alarmdecoder docs]) ([alexa docs]) ([apprise docs]) ([asuswrt docs]) ([cast docs]) ([climacell docs]) +- Merge of nested IF-IF cases - H-J ([@frenck] - [#48368]) +- Merge of nested IF-IF cases - E-G ([@frenck] - [#48367]) +- Add Maxcube unit tests ([@unaiur] - [#47872]) ([maxcube docs]) +- Remove HomeAssistantType alias from helpers ([@frenck] - [#48400]) +- Fix ability to ignore AdGuard hassio discovery ([@frenck] - [#48401]) ([adguard docs]) +- Fix entity service calls on WLED master light ([@frenck] - [#48402]) ([wled docs]) +- Bump yalexs to 1.1.9 ([@bdraco] - [#48383]) ([august docs]) +- Address late review of vesync light ([@decompil3d] - [#48130]) ([vesync docs]) +- Add Ambient Station PM25 indoor sensor ([@conflipper] - [#47970]) ([ambient_station docs]) +- Add support for selective config parameter entity discovery ([@raman325] - [#48336]) ([zwave_js docs]) +- Add broadlink dhcp discovery ([@bdraco] - [#48408]) ([broadlink docs]) +- Add template support for remaining attributes of weather entity ([@csoltenborn] - [#47736]) ([template docs]) +- ZHA lock code services and events ([@jcam] - [#47208]) ([zha docs]) +- Update mac address in broadlink test to match mocked device ([@bdraco] - [#48415]) ([broadlink docs]) +- Bump ZHA quirks to 0.0.55 ([@dmulcahey] - [#48418]) ([zha docs]) +- Remove KNX type alias for homeassistant.core types ([@farmio] - [#48422]) ([knx docs]) +- Discard outdated data reported by AEMET stations ([@Noltari] - [#48417]) ([aemet docs]) +- Allow discovery configuration of modbus platforms ([@janiversen] - [#46591]) ([modbus docs]) (breaking-change) +- Simplify maxcube integration ([@unaiur] - [#48403]) ([maxcube docs]) +- Handle routers that convert hostnames to lowercase in dhcp ([@bdraco] - [#48429]) ([dhcp docs]) ([roomba docs]) +- Fix bug in vlc_telnet seeking ([@dmcc] - [#48425]) ([vlc_telnet docs]) +- Add dsmr monthly and yearly totals ([@robertdelpeut] - [#48253]) ([dsmr_reader docs]) +- Detect when media position is stale in vlc_telnet ([@dmcc] - [#48434]) ([vlc_telnet docs]) +- Fallback to filename for title in vlc_telnet ([@dmcc] - [#48438]) ([vlc_telnet docs]) +- Add additional data source to dhcp ([@bdraco] - [#48430]) ([dhcp docs]) +- Fallback to current temperature unit for zwave_js climate ([@raman325] - [#48347]) ([zwave_js docs]) +- Bump HAP-python to 3.4.1 for homekit ([@bdraco] - [#48444]) ([homekit docs]) +- Bump aiodiscover to 1.1.2 for dhcp ([@bdraco] - [#48445]) ([dhcp docs]) +- Remove myself as codeowner of HomematicIP Cloud ([@SukramJ] - [#48437]) ([homematicip_cloud docs]) +- Address review comments from trace refactoring PRs ([@emontnemery] - [#48288]) ([automation docs]) ([script docs]) ([trace docs]) +- Speed up bond setup with gather ([@bdraco] - [#48454]) ([bond docs]) +- Bump aiodiscover to 1.2.0 in for dhcp ([@bdraco] - [#48456]) ([dhcp docs]) +- Fix template fan default speed count ([@bdraco] - [#48389]) ([fan docs]) ([template docs]) +- Fix broken trace tests ([@emontnemery] - [#48458]) ([trace docs]) +- Fix knx tests ([@mptei] - [#48407]) ([knx docs]) +- Log the reason a config entry failed to setup ([@bdraco] - [#48449]) +- Don't write 0 to next modbus register ([@PimDoos] - [#48378]) ([modbus docs]) +- Include platform only integrations in the manifest list api ([@bdraco] - [#48269]) ([device_tracker docs]) ([websocket_api docs]) +- Do not load ignored or disabled integrations at startup ([@bdraco] - [#48355]) +- Add support for Selectors in Script service fields ([@frenck] - [#48469]) ([script docs]) +- Fix unmute bug in vlc_telnet ([@dmcc] - [#48441]) ([vlc_telnet docs]) +- Allow specifying template entities based on triggers ([@balloob] - [#48169]) ([trigger docs]) (new-integration) +- Cloud: Expose if google is registered in status + check on login ([@bramkragten] - [#48260]) ([cloud docs]) +- Command template support for MQTT fan ([@jbouwh] - [#48413]) ([mqtt docs]) (breaking-change) +- Add screenshot to manifest ([@bramkragten] - [#48475]) ([frontend docs]) +- Bump zwave-js-server-python to 0.23.0 to support zwave-js 7 ([@raman325] - [#48094]) ([zwave_js docs]) (breaking-change) +- Make integration setup optional ([@frenck] - [#48381]) +- Add 'for' to cover device triggers ([@emontnemery] - [#48324]) ([cover docs]) +- Merge condition and action traces ([@emontnemery] - [#48461]) ([automation docs]) ([script docs]) ([trace docs]) +- Clean up icons & device classes for Toon ([@frenck] - [#48471]) ([toon docs]) +- Allow MQTT entities to be disabled by default ([@emontnemery] - [#48284]) ([mqtt docs]) +- Refactor fan device triggers to use ToggleEntity triggers ([@emontnemery] - [#48321]) ([fan docs]) +- Bump aiodiscover to 1.3.0 to improve performance ([@bdraco] - [#48482]) ([dhcp docs]) +- Create async_config_entry_first_refresh to reduce coordinator boilerplate ([@bdraco] - [#48451]) +- Clean up superfluous integration setup - part 1 ([@frenck] - [#48476]) +- Clean up superfluous integration setup - part 2 ([@frenck] - [#48478]) +- Clean up superfluous integration setup - part 3 ([@frenck] - [#48484]) +- Remove HomeAssistantType alias from entity components - Part 1 ([@frenck] - [#48467]) +- Remove HomeAssistantType alias from entity components - Part 2 ([@frenck] - [#48468]) +- Add asyncio locks to screenlogic api access points ([@dieselrabbit] - [#48457]) ([screenlogic docs]) +- Bump aiodiscoer to 1.3.2 for dhcp ([@bdraco] - [#48489]) ([dhcp docs]) +- Add analytics integration ([@ludeeus] - [#48256]) ([analytics docs]) ([default_config docs]) ([hassio docs]) ([onboarding docs]) (new-integration) +- Add image proxy to Kodi media browser ([@cgtobi] - [#47315]) ([kodi docs]) +- Add zwave_js.bulk_set_partial_config_parameters service ([@raman325] - [#48306]) ([zwave_js docs]) +- Update pylint to 2.7.3 ([@cdce8p] - [#48488]) +- Create new websession if more than one entry in Tesla ([@alandtse] - [#47886]) ([tesla docs]) +- Make devolo home control more robust against connection losts ([@Shutgun] - [#48328]) ([devolo_home_control docs]) +- Fixed auth issue for non-2FA iCloud accounts ([@nzapponi] - [#48455]) ([icloud docs]) +- Add opentherm_gw option for setpoint override mode ([@Martidjen] - [#48465]) ([opentherm_gw docs]) +- Bump yalexs to 1.1.10 for august ([@bdraco] - [#48494]) ([august docs]) +- Use MAX_VOLUME constant in vlc_telnet ([@dmcc] - [#48491]) ([vlc_telnet docs]) +- Include platform only integrations in analytics ([@bdraco] - [#48493]) ([analytics docs]) +- Add zwave_js.set_value service ([@raman325] - [#48487]) ([zwave_js docs]) +- Add myself as codeowner to analytics ([@ludeeus] - [#48498]) ([analytics docs]) +- Update pylint to 2.7.4 ([@cdce8p] - [#48500]) +- Add 'for' to alarm device triggers ([@emontnemery] - [#48503]) ([alarm_control_panel docs]) +- Simplify device trigger code ([@emontnemery] - [#48507]) ([alarm_control_panel docs]) ([climate docs]) ([cover docs]) ([device_automation docs]) ([lock docs]) ([vacuum docs]) +- Add support for capturing renewals to dhcp discovery ([@bdraco] - [#48242]) ([dhcp docs]) +- Add 'for' to vacuum device triggers ([@emontnemery] - [#48506]) ([vacuum docs]) +- Add 'for' to media_player device triggers ([@emontnemery] - [#48505]) ([media_player docs]) +- Add 'for' to lock device triggers ([@emontnemery] - [#48504]) ([lock docs]) +- Raise Spotify exception if no active device found ([@spacegaier] - [#48486]) ([spotify docs]) +- Add discovery for Tube's Zigbee coordinators to ZHA ([@dmulcahey] - [#48420]) ([zha docs]) +- Fix local mypy workflow ([@KapJI] - [#48433]) +- Correct FAA Delays integration domain in manifest ([@frenck] - [#48512]) ([faa_delays docs]) +- Fix duplicates and unexpected failures during roomba discovery ([@bdraco] - [#48492]) ([roomba docs]) +- KNX passive group addresses ([@farmio] - [#48009]) ([knx docs]) +- Enable strict typing for zeroconf ([@KapJI] - [#48450]) ([zeroconf docs]) +- Add regex-based filters to logger component ([@jshufro] - [#48439]) ([logger docs]) +- Evaluate AirVisual interval on reboot ([@jugla] - [#48392]) ([airvisual docs]) +- Remove analytics from updater ([@ludeeus] - [#48518]) ([updater docs]) (breaking-change) +- support feedback for ZHA device reconfiguration ([@dmulcahey] - [#48447]) ([zha docs]) +- Fix init for first added shelly device ([@mib1185] - [#48411]) ([shelly docs]) +- Search for areas used in automations and scripts ([@bramkragten] - [#48499]) ([automation docs]) ([script docs]) ([search docs]) +- Add target version to log about missing version ([@ludeeus] - [#48520]) +- Bump Synology DSM to 1.0.2 ([@Quentame] - [#48528]) ([synology_dsm docs]) +- Bump Météo-France to 1.0.2 ([@Quentame] - [#48527]) ([meteo_france docs]) +- Bump Freebox to 0.0.10 ([@Quentame] - [#48526]) ([freebox docs]) +- Bump async_upnp_client to 0.16.0 ([@StevenLooman] - [#48521]) ([dlna_dmr docs]) ([ssdp docs]) ([upnp docs]) +- Shield async httpx call in generic ([@uvjustin] - [#47852]) ([generic docs]) +- Deprecate SolarEdge YAML configuration ([@frenck] - [#48533]) ([solaredge docs]) (breaking-change) +- Remove if/else from modbus test cases ([@janiversen] - [#48514]) ([modbus docs]) +- Add color_mode support to MQTT JSON light ([@emontnemery] - [#47993]) ([light docs]) ([mqtt docs]) (breaking-change) +- Add vicare fuelcell ([@nbraem] - [#47167]) ([vicare docs]) +- Bump pyhaversion from 3.4.2 to 21.3.0 ([@ludeeus] - [#48537]) ([version docs]) +- Add missing neato error status ([@vlebourl] - [#48508]) ([neato docs]) +- Add Plex library count sensors ([@jjlawren] - [#48339]) ([plex docs]) +- Use consolidated constant for "description" ([@spacegaier] - [#48490]) +- Add id to automation triggers ([@emontnemery] - [#48464]) ([homeassistant docs]) +- Prevent ping integration from delaying startup ([@bdraco] - [#43869]) ([ping docs]) (breaking-change) +- Ensure HA script and Python script services have a name ([@spacegaier] - [#47204]) +- Improve error handling for WS API trace/get ([@emontnemery] - [#48502]) ([trace docs]) +- Set Plex sensor availability properly ([@jjlawren] - [#48546]) ([plex docs]) +- Update xknx to version 0.17.5 ([@marvin-w] - [#48522]) ([knx docs]) +- Avoid divide by zero errors in tplink light integration ([@superm1] - [#48235]) ([tplink docs]) +- Fix update of surveillance_station data in Synology DSM ([@mib1185] - [#47966]) ([synology_dsm docs]) +- Remove Hass.io terms in strings.json ([@LEJOUI] - [#48541]) ([adguard docs]) ([almond docs]) ([deconz docs]) ([mqtt docs]) +- Create homekit locks according to spec ([@bdraco] - [#48453]) ([homekit docs]) +- Update frontend to 20210331.0 ([@bramkragten] - [#48552]) ([frontend docs]) +- Improve Plex device handling ([@jjlawren] - [#48369]) ([plex docs]) +- Add operation sensor to Shelly Gas ([@chemelli74] - [#48462]) ([shelly docs]) +- Use Mapping[str, Any] instead of dict in Entity ([@KapJI] - [#48421]) +- Add Qingping Air Monitor Lite support support ([@arturdobo] - [#48181]) ([xiaomi_miio docs]) (new-integration) +- Use SOURCE_REAUTH constant for starting reauth flows ([@bdraco] - [#48553]) +- Improve automation trace tests ([@emontnemery] - [#48542]) ([trace docs]) +- Provide the improved service UX with deCONZ services ([@Kane610] - [#48382]) ([deconz docs]) + +{% enddetails %} + +[#37625]: https://github.com/home-assistant/core/pull/37625 +[#40714]: https://github.com/home-assistant/core/pull/40714 +[#41163]: https://github.com/home-assistant/core/pull/41163 +[#41193]: https://github.com/home-assistant/core/pull/41193 +[#41438]: https://github.com/home-assistant/core/pull/41438 +[#42318]: https://github.com/home-assistant/core/pull/42318 +[#42450]: https://github.com/home-assistant/core/pull/42450 +[#43588]: https://github.com/home-assistant/core/pull/43588 +[#43751]: https://github.com/home-assistant/core/pull/43751 +[#43869]: https://github.com/home-assistant/core/pull/43869 +[#44090]: https://github.com/home-assistant/core/pull/44090 +[#44582]: https://github.com/home-assistant/core/pull/44582 +[#44807]: https://github.com/home-assistant/core/pull/44807 +[#45208]: https://github.com/home-assistant/core/pull/45208 +[#45253]: https://github.com/home-assistant/core/pull/45253 +[#45398]: https://github.com/home-assistant/core/pull/45398 +[#45564]: https://github.com/home-assistant/core/pull/45564 +[#45689]: https://github.com/home-assistant/core/pull/45689 +[#45725]: https://github.com/home-assistant/core/pull/45725 +[#45727]: https://github.com/home-assistant/core/pull/45727 +[#45765]: https://github.com/home-assistant/core/pull/45765 +[#45826]: https://github.com/home-assistant/core/pull/45826 +[#45868]: https://github.com/home-assistant/core/pull/45868 +[#45994]: https://github.com/home-assistant/core/pull/45994 +[#46086]: https://github.com/home-assistant/core/pull/46086 +[#46242]: https://github.com/home-assistant/core/pull/46242 +[#46342]: https://github.com/home-assistant/core/pull/46342 +[#46347]: https://github.com/home-assistant/core/pull/46347 +[#46372]: https://github.com/home-assistant/core/pull/46372 +[#46373]: https://github.com/home-assistant/core/pull/46373 +[#46375]: https://github.com/home-assistant/core/pull/46375 +[#46380]: https://github.com/home-assistant/core/pull/46380 +[#46381]: https://github.com/home-assistant/core/pull/46381 +[#46392]: https://github.com/home-assistant/core/pull/46392 +[#46393]: https://github.com/home-assistant/core/pull/46393 +[#46396]: https://github.com/home-assistant/core/pull/46396 +[#46407]: https://github.com/home-assistant/core/pull/46407 +[#46427]: https://github.com/home-assistant/core/pull/46427 +[#46499]: https://github.com/home-assistant/core/pull/46499 +[#46573]: https://github.com/home-assistant/core/pull/46573 +[#46588]: https://github.com/home-assistant/core/pull/46588 +[#46589]: https://github.com/home-assistant/core/pull/46589 +[#46591]: https://github.com/home-assistant/core/pull/46591 +[#46593]: https://github.com/home-assistant/core/pull/46593 +[#46606]: https://github.com/home-assistant/core/pull/46606 +[#46657]: https://github.com/home-assistant/core/pull/46657 +[#46660]: https://github.com/home-assistant/core/pull/46660 +[#46671]: https://github.com/home-assistant/core/pull/46671 +[#46678]: https://github.com/home-assistant/core/pull/46678 +[#46682]: https://github.com/home-assistant/core/pull/46682 +[#46689]: https://github.com/home-assistant/core/pull/46689 +[#46696]: https://github.com/home-assistant/core/pull/46696 +[#46712]: https://github.com/home-assistant/core/pull/46712 +[#46715]: https://github.com/home-assistant/core/pull/46715 +[#46755]: https://github.com/home-assistant/core/pull/46755 +[#46761]: https://github.com/home-assistant/core/pull/46761 +[#46762]: https://github.com/home-assistant/core/pull/46762 +[#46783]: https://github.com/home-assistant/core/pull/46783 +[#46800]: https://github.com/home-assistant/core/pull/46800 +[#46861]: https://github.com/home-assistant/core/pull/46861 +[#46866]: https://github.com/home-assistant/core/pull/46866 +[#46874]: https://github.com/home-assistant/core/pull/46874 +[#46879]: https://github.com/home-assistant/core/pull/46879 +[#46882]: https://github.com/home-assistant/core/pull/46882 +[#46899]: https://github.com/home-assistant/core/pull/46899 +[#46908]: https://github.com/home-assistant/core/pull/46908 +[#46948]: https://github.com/home-assistant/core/pull/46948 +[#46964]: https://github.com/home-assistant/core/pull/46964 +[#46972]: https://github.com/home-assistant/core/pull/46972 +[#46998]: https://github.com/home-assistant/core/pull/46998 +[#47003]: https://github.com/home-assistant/core/pull/47003 +[#47008]: https://github.com/home-assistant/core/pull/47008 +[#47014]: https://github.com/home-assistant/core/pull/47014 +[#47015]: https://github.com/home-assistant/core/pull/47015 +[#47017]: https://github.com/home-assistant/core/pull/47017 +[#47019]: https://github.com/home-assistant/core/pull/47019 +[#47021]: https://github.com/home-assistant/core/pull/47021 +[#47022]: https://github.com/home-assistant/core/pull/47022 +[#47024]: https://github.com/home-assistant/core/pull/47024 +[#47026]: https://github.com/home-assistant/core/pull/47026 +[#47034]: https://github.com/home-assistant/core/pull/47034 +[#47037]: https://github.com/home-assistant/core/pull/47037 +[#47039]: https://github.com/home-assistant/core/pull/47039 +[#47041]: https://github.com/home-assistant/core/pull/47041 +[#47042]: https://github.com/home-assistant/core/pull/47042 +[#47045]: https://github.com/home-assistant/core/pull/47045 +[#47050]: https://github.com/home-assistant/core/pull/47050 +[#47052]: https://github.com/home-assistant/core/pull/47052 +[#47055]: https://github.com/home-assistant/core/pull/47055 +[#47061]: https://github.com/home-assistant/core/pull/47061 +[#47063]: https://github.com/home-assistant/core/pull/47063 +[#47074]: https://github.com/home-assistant/core/pull/47074 +[#47078]: https://github.com/home-assistant/core/pull/47078 +[#47080]: https://github.com/home-assistant/core/pull/47080 +[#47086]: https://github.com/home-assistant/core/pull/47086 +[#47096]: https://github.com/home-assistant/core/pull/47096 +[#47101]: https://github.com/home-assistant/core/pull/47101 +[#47113]: https://github.com/home-assistant/core/pull/47113 +[#47129]: https://github.com/home-assistant/core/pull/47129 +[#47133]: https://github.com/home-assistant/core/pull/47133 +[#47141]: https://github.com/home-assistant/core/pull/47141 +[#47144]: https://github.com/home-assistant/core/pull/47144 +[#47145]: https://github.com/home-assistant/core/pull/47145 +[#47148]: https://github.com/home-assistant/core/pull/47148 +[#47151]: https://github.com/home-assistant/core/pull/47151 +[#47155]: https://github.com/home-assistant/core/pull/47155 +[#47157]: https://github.com/home-assistant/core/pull/47157 +[#47161]: https://github.com/home-assistant/core/pull/47161 +[#47163]: https://github.com/home-assistant/core/pull/47163 +[#47165]: https://github.com/home-assistant/core/pull/47165 +[#47167]: https://github.com/home-assistant/core/pull/47167 +[#47169]: https://github.com/home-assistant/core/pull/47169 +[#47170]: https://github.com/home-assistant/core/pull/47170 +[#47175]: https://github.com/home-assistant/core/pull/47175 +[#47178]: https://github.com/home-assistant/core/pull/47178 +[#47184]: https://github.com/home-assistant/core/pull/47184 +[#47186]: https://github.com/home-assistant/core/pull/47186 +[#47187]: https://github.com/home-assistant/core/pull/47187 +[#47189]: https://github.com/home-assistant/core/pull/47189 +[#47190]: https://github.com/home-assistant/core/pull/47190 +[#47191]: https://github.com/home-assistant/core/pull/47191 +[#47192]: https://github.com/home-assistant/core/pull/47192 +[#47196]: https://github.com/home-assistant/core/pull/47196 +[#47204]: https://github.com/home-assistant/core/pull/47204 +[#47205]: https://github.com/home-assistant/core/pull/47205 +[#47208]: https://github.com/home-assistant/core/pull/47208 +[#47211]: https://github.com/home-assistant/core/pull/47211 +[#47218]: https://github.com/home-assistant/core/pull/47218 +[#47221]: https://github.com/home-assistant/core/pull/47221 +[#47227]: https://github.com/home-assistant/core/pull/47227 +[#47228]: https://github.com/home-assistant/core/pull/47228 +[#47229]: https://github.com/home-assistant/core/pull/47229 +[#47232]: https://github.com/home-assistant/core/pull/47232 +[#47235]: https://github.com/home-assistant/core/pull/47235 +[#47237]: https://github.com/home-assistant/core/pull/47237 +[#47238]: https://github.com/home-assistant/core/pull/47238 +[#47245]: https://github.com/home-assistant/core/pull/47245 +[#47247]: https://github.com/home-assistant/core/pull/47247 +[#47248]: https://github.com/home-assistant/core/pull/47248 +[#47249]: https://github.com/home-assistant/core/pull/47249 +[#47255]: https://github.com/home-assistant/core/pull/47255 +[#47259]: https://github.com/home-assistant/core/pull/47259 +[#47261]: https://github.com/home-assistant/core/pull/47261 +[#47269]: https://github.com/home-assistant/core/pull/47269 +[#47276]: https://github.com/home-assistant/core/pull/47276 +[#47279]: https://github.com/home-assistant/core/pull/47279 +[#47284]: https://github.com/home-assistant/core/pull/47284 +[#47285]: https://github.com/home-assistant/core/pull/47285 +[#47294]: https://github.com/home-assistant/core/pull/47294 +[#47300]: https://github.com/home-assistant/core/pull/47300 +[#47302]: https://github.com/home-assistant/core/pull/47302 +[#47304]: https://github.com/home-assistant/core/pull/47304 +[#47305]: https://github.com/home-assistant/core/pull/47305 +[#47308]: https://github.com/home-assistant/core/pull/47308 +[#47314]: https://github.com/home-assistant/core/pull/47314 +[#47315]: https://github.com/home-assistant/core/pull/47315 +[#47323]: https://github.com/home-assistant/core/pull/47323 +[#47324]: https://github.com/home-assistant/core/pull/47324 +[#47350]: https://github.com/home-assistant/core/pull/47350 +[#47373]: https://github.com/home-assistant/core/pull/47373 +[#47384]: https://github.com/home-assistant/core/pull/47384 +[#47401]: https://github.com/home-assistant/core/pull/47401 +[#47403]: https://github.com/home-assistant/core/pull/47403 +[#47411]: https://github.com/home-assistant/core/pull/47411 +[#47413]: https://github.com/home-assistant/core/pull/47413 +[#47414]: https://github.com/home-assistant/core/pull/47414 +[#47426]: https://github.com/home-assistant/core/pull/47426 +[#47431]: https://github.com/home-assistant/core/pull/47431 +[#47441]: https://github.com/home-assistant/core/pull/47441 +[#47451]: https://github.com/home-assistant/core/pull/47451 +[#47456]: https://github.com/home-assistant/core/pull/47456 +[#47470]: https://github.com/home-assistant/core/pull/47470 +[#47471]: https://github.com/home-assistant/core/pull/47471 +[#47477]: https://github.com/home-assistant/core/pull/47477 +[#47479]: https://github.com/home-assistant/core/pull/47479 +[#47480]: https://github.com/home-assistant/core/pull/47480 +[#47482]: https://github.com/home-assistant/core/pull/47482 +[#47484]: https://github.com/home-assistant/core/pull/47484 +[#47487]: https://github.com/home-assistant/core/pull/47487 +[#47488]: https://github.com/home-assistant/core/pull/47488 +[#47491]: https://github.com/home-assistant/core/pull/47491 +[#47492]: https://github.com/home-assistant/core/pull/47492 +[#47500]: https://github.com/home-assistant/core/pull/47500 +[#47501]: https://github.com/home-assistant/core/pull/47501 +[#47509]: https://github.com/home-assistant/core/pull/47509 +[#47520]: https://github.com/home-assistant/core/pull/47520 +[#47526]: https://github.com/home-assistant/core/pull/47526 +[#47528]: https://github.com/home-assistant/core/pull/47528 +[#47532]: https://github.com/home-assistant/core/pull/47532 +[#47534]: https://github.com/home-assistant/core/pull/47534 +[#47537]: https://github.com/home-assistant/core/pull/47537 +[#47539]: https://github.com/home-assistant/core/pull/47539 +[#47542]: https://github.com/home-assistant/core/pull/47542 +[#47544]: https://github.com/home-assistant/core/pull/47544 +[#47545]: https://github.com/home-assistant/core/pull/47545 +[#47547]: https://github.com/home-assistant/core/pull/47547 +[#47549]: https://github.com/home-assistant/core/pull/47549 +[#47555]: https://github.com/home-assistant/core/pull/47555 +[#47557]: https://github.com/home-assistant/core/pull/47557 +[#47559]: https://github.com/home-assistant/core/pull/47559 +[#47572]: https://github.com/home-assistant/core/pull/47572 +[#47574]: https://github.com/home-assistant/core/pull/47574 +[#47583]: https://github.com/home-assistant/core/pull/47583 +[#47584]: https://github.com/home-assistant/core/pull/47584 +[#47586]: https://github.com/home-assistant/core/pull/47586 +[#47589]: https://github.com/home-assistant/core/pull/47589 +[#47590]: https://github.com/home-assistant/core/pull/47590 +[#47601]: https://github.com/home-assistant/core/pull/47601 +[#47607]: https://github.com/home-assistant/core/pull/47607 +[#47608]: https://github.com/home-assistant/core/pull/47608 +[#47612]: https://github.com/home-assistant/core/pull/47612 +[#47615]: https://github.com/home-assistant/core/pull/47615 +[#47616]: https://github.com/home-assistant/core/pull/47616 +[#47617]: https://github.com/home-assistant/core/pull/47617 +[#47618]: https://github.com/home-assistant/core/pull/47618 +[#47619]: https://github.com/home-assistant/core/pull/47619 +[#47621]: https://github.com/home-assistant/core/pull/47621 +[#47626]: https://github.com/home-assistant/core/pull/47626 +[#47627]: https://github.com/home-assistant/core/pull/47627 +[#47632]: https://github.com/home-assistant/core/pull/47632 +[#47638]: https://github.com/home-assistant/core/pull/47638 +[#47639]: https://github.com/home-assistant/core/pull/47639 +[#47641]: https://github.com/home-assistant/core/pull/47641 +[#47642]: https://github.com/home-assistant/core/pull/47642 +[#47643]: https://github.com/home-assistant/core/pull/47643 +[#47651]: https://github.com/home-assistant/core/pull/47651 +[#47652]: https://github.com/home-assistant/core/pull/47652 +[#47653]: https://github.com/home-assistant/core/pull/47653 +[#47654]: https://github.com/home-assistant/core/pull/47654 +[#47655]: https://github.com/home-assistant/core/pull/47655 +[#47664]: https://github.com/home-assistant/core/pull/47664 +[#47666]: https://github.com/home-assistant/core/pull/47666 +[#47668]: https://github.com/home-assistant/core/pull/47668 +[#47669]: https://github.com/home-assistant/core/pull/47669 +[#47676]: https://github.com/home-assistant/core/pull/47676 +[#47680]: https://github.com/home-assistant/core/pull/47680 +[#47681]: https://github.com/home-assistant/core/pull/47681 +[#47683]: https://github.com/home-assistant/core/pull/47683 +[#47684]: https://github.com/home-assistant/core/pull/47684 +[#47696]: https://github.com/home-assistant/core/pull/47696 +[#47702]: https://github.com/home-assistant/core/pull/47702 +[#47705]: https://github.com/home-assistant/core/pull/47705 +[#47706]: https://github.com/home-assistant/core/pull/47706 +[#47707]: https://github.com/home-assistant/core/pull/47707 +[#47718]: https://github.com/home-assistant/core/pull/47718 +[#47719]: https://github.com/home-assistant/core/pull/47719 +[#47720]: https://github.com/home-assistant/core/pull/47720 +[#47721]: https://github.com/home-assistant/core/pull/47721 +[#47722]: https://github.com/home-assistant/core/pull/47722 +[#47725]: https://github.com/home-assistant/core/pull/47725 +[#47729]: https://github.com/home-assistant/core/pull/47729 +[#47732]: https://github.com/home-assistant/core/pull/47732 +[#47736]: https://github.com/home-assistant/core/pull/47736 +[#47737]: https://github.com/home-assistant/core/pull/47737 +[#47739]: https://github.com/home-assistant/core/pull/47739 +[#47741]: https://github.com/home-assistant/core/pull/47741 +[#47744]: https://github.com/home-assistant/core/pull/47744 +[#47745]: https://github.com/home-assistant/core/pull/47745 +[#47746]: https://github.com/home-assistant/core/pull/47746 +[#47754]: https://github.com/home-assistant/core/pull/47754 +[#47756]: https://github.com/home-assistant/core/pull/47756 +[#47757]: https://github.com/home-assistant/core/pull/47757 +[#47758]: https://github.com/home-assistant/core/pull/47758 +[#47759]: https://github.com/home-assistant/core/pull/47759 +[#47760]: https://github.com/home-assistant/core/pull/47760 +[#47770]: https://github.com/home-assistant/core/pull/47770 +[#47771]: https://github.com/home-assistant/core/pull/47771 +[#47774]: https://github.com/home-assistant/core/pull/47774 +[#47778]: https://github.com/home-assistant/core/pull/47778 +[#47779]: https://github.com/home-assistant/core/pull/47779 +[#47783]: https://github.com/home-assistant/core/pull/47783 +[#47785]: https://github.com/home-assistant/core/pull/47785 +[#47790]: https://github.com/home-assistant/core/pull/47790 +[#47791]: https://github.com/home-assistant/core/pull/47791 +[#47795]: https://github.com/home-assistant/core/pull/47795 +[#47798]: https://github.com/home-assistant/core/pull/47798 +[#47800]: https://github.com/home-assistant/core/pull/47800 +[#47802]: https://github.com/home-assistant/core/pull/47802 +[#47803]: https://github.com/home-assistant/core/pull/47803 +[#47806]: https://github.com/home-assistant/core/pull/47806 +[#47808]: https://github.com/home-assistant/core/pull/47808 +[#47809]: https://github.com/home-assistant/core/pull/47809 +[#47812]: https://github.com/home-assistant/core/pull/47812 +[#47818]: https://github.com/home-assistant/core/pull/47818 +[#47819]: https://github.com/home-assistant/core/pull/47819 +[#47820]: https://github.com/home-assistant/core/pull/47820 +[#47821]: https://github.com/home-assistant/core/pull/47821 +[#47822]: https://github.com/home-assistant/core/pull/47822 +[#47823]: https://github.com/home-assistant/core/pull/47823 +[#47824]: https://github.com/home-assistant/core/pull/47824 +[#47825]: https://github.com/home-assistant/core/pull/47825 +[#47826]: https://github.com/home-assistant/core/pull/47826 +[#47827]: https://github.com/home-assistant/core/pull/47827 +[#47829]: https://github.com/home-assistant/core/pull/47829 +[#47830]: https://github.com/home-assistant/core/pull/47830 +[#47831]: https://github.com/home-assistant/core/pull/47831 +[#47832]: https://github.com/home-assistant/core/pull/47832 +[#47836]: https://github.com/home-assistant/core/pull/47836 +[#47837]: https://github.com/home-assistant/core/pull/47837 +[#47840]: https://github.com/home-assistant/core/pull/47840 +[#47844]: https://github.com/home-assistant/core/pull/47844 +[#47846]: https://github.com/home-assistant/core/pull/47846 +[#47848]: https://github.com/home-assistant/core/pull/47848 +[#47851]: https://github.com/home-assistant/core/pull/47851 +[#47852]: https://github.com/home-assistant/core/pull/47852 +[#47854]: https://github.com/home-assistant/core/pull/47854 +[#47856]: https://github.com/home-assistant/core/pull/47856 +[#47857]: https://github.com/home-assistant/core/pull/47857 +[#47858]: https://github.com/home-assistant/core/pull/47858 +[#47869]: https://github.com/home-assistant/core/pull/47869 +[#47870]: https://github.com/home-assistant/core/pull/47870 +[#47871]: https://github.com/home-assistant/core/pull/47871 +[#47872]: https://github.com/home-assistant/core/pull/47872 +[#47873]: https://github.com/home-assistant/core/pull/47873 +[#47876]: https://github.com/home-assistant/core/pull/47876 +[#47880]: https://github.com/home-assistant/core/pull/47880 +[#47886]: https://github.com/home-assistant/core/pull/47886 +[#47890]: https://github.com/home-assistant/core/pull/47890 +[#47892]: https://github.com/home-assistant/core/pull/47892 +[#47899]: https://github.com/home-assistant/core/pull/47899 +[#47903]: https://github.com/home-assistant/core/pull/47903 +[#47905]: https://github.com/home-assistant/core/pull/47905 +[#47906]: https://github.com/home-assistant/core/pull/47906 +[#47907]: https://github.com/home-assistant/core/pull/47907 +[#47910]: https://github.com/home-assistant/core/pull/47910 +[#47913]: https://github.com/home-assistant/core/pull/47913 +[#47915]: https://github.com/home-assistant/core/pull/47915 +[#47917]: https://github.com/home-assistant/core/pull/47917 +[#47919]: https://github.com/home-assistant/core/pull/47919 +[#47927]: https://github.com/home-assistant/core/pull/47927 +[#47929]: https://github.com/home-assistant/core/pull/47929 +[#47930]: https://github.com/home-assistant/core/pull/47930 +[#47932]: https://github.com/home-assistant/core/pull/47932 +[#47933]: https://github.com/home-assistant/core/pull/47933 +[#47935]: https://github.com/home-assistant/core/pull/47935 +[#47940]: https://github.com/home-assistant/core/pull/47940 +[#47942]: https://github.com/home-assistant/core/pull/47942 +[#47944]: https://github.com/home-assistant/core/pull/47944 +[#47945]: https://github.com/home-assistant/core/pull/47945 +[#47946]: https://github.com/home-assistant/core/pull/47946 +[#47949]: https://github.com/home-assistant/core/pull/47949 +[#47953]: https://github.com/home-assistant/core/pull/47953 +[#47954]: https://github.com/home-assistant/core/pull/47954 +[#47956]: https://github.com/home-assistant/core/pull/47956 +[#47957]: https://github.com/home-assistant/core/pull/47957 +[#47960]: https://github.com/home-assistant/core/pull/47960 +[#47964]: https://github.com/home-assistant/core/pull/47964 +[#47966]: https://github.com/home-assistant/core/pull/47966 +[#47967]: https://github.com/home-assistant/core/pull/47967 +[#47970]: https://github.com/home-assistant/core/pull/47970 +[#47972]: https://github.com/home-assistant/core/pull/47972 +[#47973]: https://github.com/home-assistant/core/pull/47973 +[#47975]: https://github.com/home-assistant/core/pull/47975 +[#47980]: https://github.com/home-assistant/core/pull/47980 +[#47990]: https://github.com/home-assistant/core/pull/47990 +[#47993]: https://github.com/home-assistant/core/pull/47993 +[#47996]: https://github.com/home-assistant/core/pull/47996 +[#47997]: https://github.com/home-assistant/core/pull/47997 +[#48000]: https://github.com/home-assistant/core/pull/48000 +[#48001]: https://github.com/home-assistant/core/pull/48001 +[#48005]: https://github.com/home-assistant/core/pull/48005 +[#48009]: https://github.com/home-assistant/core/pull/48009 +[#48012]: https://github.com/home-assistant/core/pull/48012 +[#48013]: https://github.com/home-assistant/core/pull/48013 +[#48014]: https://github.com/home-assistant/core/pull/48014 +[#48015]: https://github.com/home-assistant/core/pull/48015 +[#48020]: https://github.com/home-assistant/core/pull/48020 +[#48029]: https://github.com/home-assistant/core/pull/48029 +[#48031]: https://github.com/home-assistant/core/pull/48031 +[#48033]: https://github.com/home-assistant/core/pull/48033 +[#48037]: https://github.com/home-assistant/core/pull/48037 +[#48038]: https://github.com/home-assistant/core/pull/48038 +[#48039]: https://github.com/home-assistant/core/pull/48039 +[#48041]: https://github.com/home-assistant/core/pull/48041 +[#48044]: https://github.com/home-assistant/core/pull/48044 +[#48045]: https://github.com/home-assistant/core/pull/48045 +[#48046]: https://github.com/home-assistant/core/pull/48046 +[#48047]: https://github.com/home-assistant/core/pull/48047 +[#48050]: https://github.com/home-assistant/core/pull/48050 +[#48051]: https://github.com/home-assistant/core/pull/48051 +[#48053]: https://github.com/home-assistant/core/pull/48053 +[#48054]: https://github.com/home-assistant/core/pull/48054 +[#48055]: https://github.com/home-assistant/core/pull/48055 +[#48056]: https://github.com/home-assistant/core/pull/48056 +[#48057]: https://github.com/home-assistant/core/pull/48057 +[#48058]: https://github.com/home-assistant/core/pull/48058 +[#48059]: https://github.com/home-assistant/core/pull/48059 +[#48062]: https://github.com/home-assistant/core/pull/48062 +[#48064]: https://github.com/home-assistant/core/pull/48064 +[#48065]: https://github.com/home-assistant/core/pull/48065 +[#48071]: https://github.com/home-assistant/core/pull/48071 +[#48072]: https://github.com/home-assistant/core/pull/48072 +[#48073]: https://github.com/home-assistant/core/pull/48073 +[#48076]: https://github.com/home-assistant/core/pull/48076 +[#48077]: https://github.com/home-assistant/core/pull/48077 +[#48078]: https://github.com/home-assistant/core/pull/48078 +[#48079]: https://github.com/home-assistant/core/pull/48079 +[#48081]: https://github.com/home-assistant/core/pull/48081 +[#48087]: https://github.com/home-assistant/core/pull/48087 +[#48088]: https://github.com/home-assistant/core/pull/48088 +[#48089]: https://github.com/home-assistant/core/pull/48089 +[#48090]: https://github.com/home-assistant/core/pull/48090 +[#48091]: https://github.com/home-assistant/core/pull/48091 +[#48094]: https://github.com/home-assistant/core/pull/48094 +[#48096]: https://github.com/home-assistant/core/pull/48096 +[#48097]: https://github.com/home-assistant/core/pull/48097 +[#48100]: https://github.com/home-assistant/core/pull/48100 +[#48106]: https://github.com/home-assistant/core/pull/48106 +[#48111]: https://github.com/home-assistant/core/pull/48111 +[#48112]: https://github.com/home-assistant/core/pull/48112 +[#48119]: https://github.com/home-assistant/core/pull/48119 +[#48125]: https://github.com/home-assistant/core/pull/48125 +[#48126]: https://github.com/home-assistant/core/pull/48126 +[#48127]: https://github.com/home-assistant/core/pull/48127 +[#48128]: https://github.com/home-assistant/core/pull/48128 +[#48129]: https://github.com/home-assistant/core/pull/48129 +[#48130]: https://github.com/home-assistant/core/pull/48130 +[#48132]: https://github.com/home-assistant/core/pull/48132 +[#48133]: https://github.com/home-assistant/core/pull/48133 +[#48135]: https://github.com/home-assistant/core/pull/48135 +[#48136]: https://github.com/home-assistant/core/pull/48136 +[#48140]: https://github.com/home-assistant/core/pull/48140 +[#48141]: https://github.com/home-assistant/core/pull/48141 +[#48142]: https://github.com/home-assistant/core/pull/48142 +[#48146]: https://github.com/home-assistant/core/pull/48146 +[#48147]: https://github.com/home-assistant/core/pull/48147 +[#48149]: https://github.com/home-assistant/core/pull/48149 +[#48150]: https://github.com/home-assistant/core/pull/48150 +[#48152]: https://github.com/home-assistant/core/pull/48152 +[#48161]: https://github.com/home-assistant/core/pull/48161 +[#48162]: https://github.com/home-assistant/core/pull/48162 +[#48163]: https://github.com/home-assistant/core/pull/48163 +[#48167]: https://github.com/home-assistant/core/pull/48167 +[#48168]: https://github.com/home-assistant/core/pull/48168 +[#48169]: https://github.com/home-assistant/core/pull/48169 +[#48175]: https://github.com/home-assistant/core/pull/48175 +[#48176]: https://github.com/home-assistant/core/pull/48176 +[#48178]: https://github.com/home-assistant/core/pull/48178 +[#48181]: https://github.com/home-assistant/core/pull/48181 +[#48184]: https://github.com/home-assistant/core/pull/48184 +[#48187]: https://github.com/home-assistant/core/pull/48187 +[#48189]: https://github.com/home-assistant/core/pull/48189 +[#48193]: https://github.com/home-assistant/core/pull/48193 +[#48196]: https://github.com/home-assistant/core/pull/48196 +[#48199]: https://github.com/home-assistant/core/pull/48199 +[#48201]: https://github.com/home-assistant/core/pull/48201 +[#48202]: https://github.com/home-assistant/core/pull/48202 +[#48203]: https://github.com/home-assistant/core/pull/48203 +[#48205]: https://github.com/home-assistant/core/pull/48205 +[#48209]: https://github.com/home-assistant/core/pull/48209 +[#48210]: https://github.com/home-assistant/core/pull/48210 +[#48211]: https://github.com/home-assistant/core/pull/48211 +[#48212]: https://github.com/home-assistant/core/pull/48212 +[#48213]: https://github.com/home-assistant/core/pull/48213 +[#48214]: https://github.com/home-assistant/core/pull/48214 +[#48215]: https://github.com/home-assistant/core/pull/48215 +[#48216]: https://github.com/home-assistant/core/pull/48216 +[#48217]: https://github.com/home-assistant/core/pull/48217 +[#48218]: https://github.com/home-assistant/core/pull/48218 +[#48219]: https://github.com/home-assistant/core/pull/48219 +[#48220]: https://github.com/home-assistant/core/pull/48220 +[#48223]: https://github.com/home-assistant/core/pull/48223 +[#48224]: https://github.com/home-assistant/core/pull/48224 +[#48230]: https://github.com/home-assistant/core/pull/48230 +[#48231]: https://github.com/home-assistant/core/pull/48231 +[#48232]: https://github.com/home-assistant/core/pull/48232 +[#48233]: https://github.com/home-assistant/core/pull/48233 +[#48235]: https://github.com/home-assistant/core/pull/48235 +[#48242]: https://github.com/home-assistant/core/pull/48242 +[#48243]: https://github.com/home-assistant/core/pull/48243 +[#48244]: https://github.com/home-assistant/core/pull/48244 +[#48245]: https://github.com/home-assistant/core/pull/48245 +[#48250]: https://github.com/home-assistant/core/pull/48250 +[#48253]: https://github.com/home-assistant/core/pull/48253 +[#48254]: https://github.com/home-assistant/core/pull/48254 +[#48256]: https://github.com/home-assistant/core/pull/48256 +[#48257]: https://github.com/home-assistant/core/pull/48257 +[#48260]: https://github.com/home-assistant/core/pull/48260 +[#48264]: https://github.com/home-assistant/core/pull/48264 +[#48268]: https://github.com/home-assistant/core/pull/48268 +[#48269]: https://github.com/home-assistant/core/pull/48269 +[#48272]: https://github.com/home-assistant/core/pull/48272 +[#48273]: https://github.com/home-assistant/core/pull/48273 +[#48276]: https://github.com/home-assistant/core/pull/48276 +[#48277]: https://github.com/home-assistant/core/pull/48277 +[#48279]: https://github.com/home-assistant/core/pull/48279 +[#48284]: https://github.com/home-assistant/core/pull/48284 +[#48288]: https://github.com/home-assistant/core/pull/48288 +[#48291]: https://github.com/home-assistant/core/pull/48291 +[#48292]: https://github.com/home-assistant/core/pull/48292 +[#48296]: https://github.com/home-assistant/core/pull/48296 +[#48298]: https://github.com/home-assistant/core/pull/48298 +[#48302]: https://github.com/home-assistant/core/pull/48302 +[#48303]: https://github.com/home-assistant/core/pull/48303 +[#48304]: https://github.com/home-assistant/core/pull/48304 +[#48306]: https://github.com/home-assistant/core/pull/48306 +[#48307]: https://github.com/home-assistant/core/pull/48307 +[#48311]: https://github.com/home-assistant/core/pull/48311 +[#48313]: https://github.com/home-assistant/core/pull/48313 +[#48316]: https://github.com/home-assistant/core/pull/48316 +[#48317]: https://github.com/home-assistant/core/pull/48317 +[#48319]: https://github.com/home-assistant/core/pull/48319 +[#48321]: https://github.com/home-assistant/core/pull/48321 +[#48324]: https://github.com/home-assistant/core/pull/48324 +[#48326]: https://github.com/home-assistant/core/pull/48326 +[#48328]: https://github.com/home-assistant/core/pull/48328 +[#48330]: https://github.com/home-assistant/core/pull/48330 +[#48333]: https://github.com/home-assistant/core/pull/48333 +[#48336]: https://github.com/home-assistant/core/pull/48336 +[#48339]: https://github.com/home-assistant/core/pull/48339 +[#48340]: https://github.com/home-assistant/core/pull/48340 +[#48343]: https://github.com/home-assistant/core/pull/48343 +[#48347]: https://github.com/home-assistant/core/pull/48347 +[#48349]: https://github.com/home-assistant/core/pull/48349 +[#48350]: https://github.com/home-assistant/core/pull/48350 +[#48351]: https://github.com/home-assistant/core/pull/48351 +[#48353]: https://github.com/home-assistant/core/pull/48353 +[#48355]: https://github.com/home-assistant/core/pull/48355 +[#48364]: https://github.com/home-assistant/core/pull/48364 +[#48365]: https://github.com/home-assistant/core/pull/48365 +[#48366]: https://github.com/home-assistant/core/pull/48366 +[#48367]: https://github.com/home-assistant/core/pull/48367 +[#48368]: https://github.com/home-assistant/core/pull/48368 +[#48369]: https://github.com/home-assistant/core/pull/48369 +[#48370]: https://github.com/home-assistant/core/pull/48370 +[#48371]: https://github.com/home-assistant/core/pull/48371 +[#48372]: https://github.com/home-assistant/core/pull/48372 +[#48373]: https://github.com/home-assistant/core/pull/48373 +[#48374]: https://github.com/home-assistant/core/pull/48374 +[#48375]: https://github.com/home-assistant/core/pull/48375 +[#48377]: https://github.com/home-assistant/core/pull/48377 +[#48378]: https://github.com/home-assistant/core/pull/48378 +[#48381]: https://github.com/home-assistant/core/pull/48381 +[#48382]: https://github.com/home-assistant/core/pull/48382 +[#48383]: https://github.com/home-assistant/core/pull/48383 +[#48387]: https://github.com/home-assistant/core/pull/48387 +[#48388]: https://github.com/home-assistant/core/pull/48388 +[#48389]: https://github.com/home-assistant/core/pull/48389 +[#48390]: https://github.com/home-assistant/core/pull/48390 +[#48391]: https://github.com/home-assistant/core/pull/48391 +[#48392]: https://github.com/home-assistant/core/pull/48392 +[#48393]: https://github.com/home-assistant/core/pull/48393 +[#48400]: https://github.com/home-assistant/core/pull/48400 +[#48401]: https://github.com/home-assistant/core/pull/48401 +[#48402]: https://github.com/home-assistant/core/pull/48402 +[#48403]: https://github.com/home-assistant/core/pull/48403 +[#48407]: https://github.com/home-assistant/core/pull/48407 +[#48408]: https://github.com/home-assistant/core/pull/48408 +[#48411]: https://github.com/home-assistant/core/pull/48411 +[#48413]: https://github.com/home-assistant/core/pull/48413 +[#48415]: https://github.com/home-assistant/core/pull/48415 +[#48417]: https://github.com/home-assistant/core/pull/48417 +[#48418]: https://github.com/home-assistant/core/pull/48418 +[#48420]: https://github.com/home-assistant/core/pull/48420 +[#48421]: https://github.com/home-assistant/core/pull/48421 +[#48422]: https://github.com/home-assistant/core/pull/48422 +[#48425]: https://github.com/home-assistant/core/pull/48425 +[#48429]: https://github.com/home-assistant/core/pull/48429 +[#48430]: https://github.com/home-assistant/core/pull/48430 +[#48433]: https://github.com/home-assistant/core/pull/48433 +[#48434]: https://github.com/home-assistant/core/pull/48434 +[#48437]: https://github.com/home-assistant/core/pull/48437 +[#48438]: https://github.com/home-assistant/core/pull/48438 +[#48439]: https://github.com/home-assistant/core/pull/48439 +[#48441]: https://github.com/home-assistant/core/pull/48441 +[#48444]: https://github.com/home-assistant/core/pull/48444 +[#48445]: https://github.com/home-assistant/core/pull/48445 +[#48447]: https://github.com/home-assistant/core/pull/48447 +[#48449]: https://github.com/home-assistant/core/pull/48449 +[#48450]: https://github.com/home-assistant/core/pull/48450 +[#48451]: https://github.com/home-assistant/core/pull/48451 +[#48453]: https://github.com/home-assistant/core/pull/48453 +[#48454]: https://github.com/home-assistant/core/pull/48454 +[#48455]: https://github.com/home-assistant/core/pull/48455 +[#48456]: https://github.com/home-assistant/core/pull/48456 +[#48457]: https://github.com/home-assistant/core/pull/48457 +[#48458]: https://github.com/home-assistant/core/pull/48458 +[#48461]: https://github.com/home-assistant/core/pull/48461 +[#48462]: https://github.com/home-assistant/core/pull/48462 +[#48464]: https://github.com/home-assistant/core/pull/48464 +[#48465]: https://github.com/home-assistant/core/pull/48465 +[#48467]: https://github.com/home-assistant/core/pull/48467 +[#48468]: https://github.com/home-assistant/core/pull/48468 +[#48469]: https://github.com/home-assistant/core/pull/48469 +[#48471]: https://github.com/home-assistant/core/pull/48471 +[#48475]: https://github.com/home-assistant/core/pull/48475 +[#48476]: https://github.com/home-assistant/core/pull/48476 +[#48478]: https://github.com/home-assistant/core/pull/48478 +[#48482]: https://github.com/home-assistant/core/pull/48482 +[#48484]: https://github.com/home-assistant/core/pull/48484 +[#48486]: https://github.com/home-assistant/core/pull/48486 +[#48487]: https://github.com/home-assistant/core/pull/48487 +[#48488]: https://github.com/home-assistant/core/pull/48488 +[#48489]: https://github.com/home-assistant/core/pull/48489 +[#48490]: https://github.com/home-assistant/core/pull/48490 +[#48491]: https://github.com/home-assistant/core/pull/48491 +[#48492]: https://github.com/home-assistant/core/pull/48492 +[#48493]: https://github.com/home-assistant/core/pull/48493 +[#48494]: https://github.com/home-assistant/core/pull/48494 +[#48498]: https://github.com/home-assistant/core/pull/48498 +[#48499]: https://github.com/home-assistant/core/pull/48499 +[#48500]: https://github.com/home-assistant/core/pull/48500 +[#48502]: https://github.com/home-assistant/core/pull/48502 +[#48503]: https://github.com/home-assistant/core/pull/48503 +[#48504]: https://github.com/home-assistant/core/pull/48504 +[#48505]: https://github.com/home-assistant/core/pull/48505 +[#48506]: https://github.com/home-assistant/core/pull/48506 +[#48507]: https://github.com/home-assistant/core/pull/48507 +[#48508]: https://github.com/home-assistant/core/pull/48508 +[#48512]: https://github.com/home-assistant/core/pull/48512 +[#48514]: https://github.com/home-assistant/core/pull/48514 +[#48518]: https://github.com/home-assistant/core/pull/48518 +[#48520]: https://github.com/home-assistant/core/pull/48520 +[#48521]: https://github.com/home-assistant/core/pull/48521 +[#48522]: https://github.com/home-assistant/core/pull/48522 +[#48526]: https://github.com/home-assistant/core/pull/48526 +[#48527]: https://github.com/home-assistant/core/pull/48527 +[#48528]: https://github.com/home-assistant/core/pull/48528 +[#48533]: https://github.com/home-assistant/core/pull/48533 +[#48537]: https://github.com/home-assistant/core/pull/48537 +[#48541]: https://github.com/home-assistant/core/pull/48541 +[#48542]: https://github.com/home-assistant/core/pull/48542 +[#48546]: https://github.com/home-assistant/core/pull/48546 +[#48552]: https://github.com/home-assistant/core/pull/48552 +[#48553]: https://github.com/home-assistant/core/pull/48553 +[@Adminiuga]: https://github.com/Adminiuga +[@Antoni-Czaplicki]: https://github.com/Antoni-Czaplicki +[@B-Hartley]: https://github.com/B-Hartley +[@BoresXP]: https://github.com/BoresXP +[@Cooper-Dale]: https://github.com/Cooper-Dale +[@CurrentThread]: https://github.com/CurrentThread +[@D3v01dZA]: https://github.com/D3v01dZA +[@Danielhiversen]: https://github.com/Danielhiversen +[@FHeilmann]: https://github.com/FHeilmann +[@FidgetyRat]: https://github.com/FidgetyRat +[@G-Two]: https://github.com/G-Two +[@KJonline]: https://github.com/KJonline +[@Kane610]: https://github.com/Kane610 +[@KapJI]: https://github.com/KapJI +[@KartoffelToby]: https://github.com/KartoffelToby +[@LEJOUI]: https://github.com/LEJOUI +[@Martidjen]: https://github.com/Martidjen +[@MartinHjelmare]: https://github.com/MartinHjelmare +[@MatsNl]: https://github.com/MatsNl +[@Melantrix]: https://github.com/Melantrix +[@N1c093]: https://github.com/N1c093 +[@Nick-Adams-AU]: https://github.com/Nick-Adams-AU +[@Noltari]: https://github.com/Noltari +[@OttoWinter]: https://github.com/OttoWinter +[@PimDoos]: https://github.com/PimDoos +[@Quentame]: https://github.com/Quentame +[@RadekHvizdos]: https://github.com/RadekHvizdos +[@Shutgun]: https://github.com/Shutgun +[@Socalix]: https://github.com/Socalix +[@StevenLooman]: https://github.com/StevenLooman +[@SukramJ]: https://github.com/SukramJ +[@TheNetAdmin]: https://github.com/TheNetAdmin +[@abmantis]: https://github.com/abmantis +[@adamjernst]: https://github.com/adamjernst +[@alandtse]: https://github.com/alandtse +[@alengwenus]: https://github.com/alengwenus +[@allenporter]: https://github.com/allenporter +[@amelchio]: https://github.com/amelchio +[@andreas-amlabs]: https://github.com/andreas-amlabs +[@andreasbrett]: https://github.com/andreasbrett +[@arturdobo]: https://github.com/arturdobo +[@austinmroczek]: https://github.com/austinmroczek +[@balloob]: https://github.com/balloob +[@bdr99]: https://github.com/bdr99 +[@bdraco]: https://github.com/bdraco +[@bernimoses]: https://github.com/bernimoses +[@bestlibre]: https://github.com/bestlibre +[@bieniu]: https://github.com/bieniu +[@billsq]: https://github.com/billsq +[@blejdfist]: https://github.com/blejdfist +[@bramkragten]: https://github.com/bramkragten +[@c99koder]: https://github.com/c99koder +[@cdce8p]: https://github.com/cdce8p +[@cgarwood]: https://github.com/cgarwood +[@cgtobi]: https://github.com/cgtobi +[@chemaaa]: https://github.com/chemaaa +[@chemelli74]: https://github.com/chemelli74 +[@chilicheech]: https://github.com/chilicheech +[@chpego]: https://github.com/chpego +[@clssn]: https://github.com/clssn +[@colinodell]: https://github.com/colinodell +[@conflipper]: https://github.com/conflipper +[@corneyl]: https://github.com/corneyl +[@csoltenborn]: https://github.com/csoltenborn +[@ctalkington]: https://github.com/ctalkington +[@danielperna84]: https://github.com/danielperna84 +[@decompil3d]: https://github.com/decompil3d +[@dermotduffy]: https://github.com/dermotduffy +[@dewet22]: https://github.com/dewet22 +[@dgomes]: https://github.com/dgomes +[@dieselrabbit]: https://github.com/dieselrabbit +[@djtimca]: https://github.com/djtimca +[@dmcc]: https://github.com/dmcc +[@dmulcahey]: https://github.com/dmulcahey +[@drzony]: https://github.com/drzony +[@eifinger]: https://github.com/eifinger +[@eltociear]: https://github.com/eltociear +[@elupus]: https://github.com/elupus +[@elyobelyob]: https://github.com/elyobelyob +[@emlove]: https://github.com/emlove +[@emontnemery]: https://github.com/emontnemery +[@esev]: https://github.com/esev +[@fabaff]: https://github.com/fabaff +[@farmio]: https://github.com/farmio +[@felipediel]: https://github.com/felipediel +[@firstof9]: https://github.com/firstof9 +[@fredrike]: https://github.com/fredrike +[@freekode]: https://github.com/freekode +[@frenck]: https://github.com/frenck +[@fronzbot]: https://github.com/fronzbot +[@glmnet]: https://github.com/glmnet +[@hanskroner]: https://github.com/hanskroner +[@heythisisnate]: https://github.com/heythisisnate +[@hung2kgithub]: https://github.com/hung2kgithub +[@iMicknl]: https://github.com/iMicknl +[@inetAnt]: https://github.com/inetAnt +[@janiversen]: https://github.com/janiversen +[@javicalle]: https://github.com/javicalle +[@jbouwh]: https://github.com/jbouwh +[@jcam]: https://github.com/jcam +[@jdeath]: https://github.com/jdeath +[@jjlawren]: https://github.com/jjlawren +[@jnimmo]: https://github.com/jnimmo +[@joogps]: https://github.com/joogps +[@jplitza]: https://github.com/jplitza +[@jshufro]: https://github.com/jshufro +[@jugla]: https://github.com/jugla +[@keis]: https://github.com/keis +[@klaasnicolaas]: https://github.com/klaasnicolaas +[@klada]: https://github.com/klada +[@kristianheljas]: https://github.com/kristianheljas +[@ludeeus]: https://github.com/ludeeus +[@marvin-w]: https://github.com/marvin-w +[@mdonoughe]: https://github.com/mdonoughe +[@mdz]: https://github.com/mdz +[@mib1185]: https://github.com/mib1185 +[@miccico]: https://github.com/miccico +[@milanmeu]: https://github.com/milanmeu +[@mkeesey]: https://github.com/mkeesey +[@mptei]: https://github.com/mptei +[@natekspencer]: https://github.com/natekspencer +[@nbraem]: https://github.com/nbraem +[@newAM]: https://github.com/newAM +[@ntilley905]: https://github.com/ntilley905 +[@nzapponi]: https://github.com/nzapponi +[@ollo69]: https://github.com/ollo69 +[@papajojo]: https://github.com/papajojo +[@pavoni]: https://github.com/pavoni +[@pdecat]: https://github.com/pdecat +[@plomosits]: https://github.com/plomosits +[@postlund]: https://github.com/postlund +[@ppetru]: https://github.com/ppetru +[@rajlaud]: https://github.com/rajlaud +[@raman325]: https://github.com/raman325 +[@rlehfeld]: https://github.com/rlehfeld +[@robertdelpeut]: https://github.com/robertdelpeut +[@ronaldheft]: https://github.com/ronaldheft +[@scarface-4711]: https://github.com/scarface-4711 +[@schiermi]: https://github.com/schiermi +[@scop]: https://github.com/scop +[@scyto]: https://github.com/scyto +[@spacegaier]: https://github.com/spacegaier +[@starkillerOG]: https://github.com/starkillerOG +[@stephan192]: https://github.com/stephan192 +[@superm1]: https://github.com/superm1 +[@swilson]: https://github.com/swilson +[@sycx2]: https://github.com/sycx2 +[@systemcrash]: https://github.com/systemcrash +[@tdorsey]: https://github.com/tdorsey +[@thecode]: https://github.com/thecode +[@timmo001]: https://github.com/timmo001 +[@tkdrob]: https://github.com/tkdrob +[@unaiur]: https://github.com/unaiur +[@uvjustin]: https://github.com/uvjustin +[@vlebourl]: https://github.com/vlebourl +[@w1ll1am23]: https://github.com/w1ll1am23 +[@xonestonex]: https://github.com/xonestonex +[@zxdavb]: https://github.com/zxdavb +[accuweather docs]: /integrations/accuweather/ +[acmeda docs]: /integrations/acmeda/ +[adguard docs]: /integrations/adguard/ +[aemet docs]: /integrations/aemet/ +[agent_dvr docs]: /integrations/agent_dvr/ +[airly docs]: /integrations/airly/ +[airvisual docs]: /integrations/airvisual/ +[alarm_control_panel docs]: /integrations/alarm_control_panel/ +[alarmdecoder docs]: /integrations/alarmdecoder/ +[alexa docs]: /integrations/alexa/ +[almond docs]: /integrations/almond/ +[ambiclimate docs]: /integrations/ambiclimate/ +[ambient_station docs]: /integrations/ambient_station/ +[amcrest docs]: /integrations/amcrest/ +[analytics docs]: /integrations/analytics/ +[api docs]: /integrations/api/ +[apple_tv docs]: /integrations/apple_tv/ +[apprise docs]: /integrations/apprise/ +[aqualogic docs]: /integrations/aqualogic/ +[asuswrt docs]: /integrations/asuswrt/ +[atag docs]: /integrations/atag/ +[august docs]: /integrations/august/ +[automation docs]: /integrations/automation/ +[awair docs]: /integrations/awair/ +[blink docs]: /integrations/blink/ +[bmp280 docs]: /integrations/bmp280/ +[bond docs]: /integrations/bond/ +[broadlink docs]: /integrations/broadlink/ +[brother docs]: /integrations/brother/ +[buienradar docs]: /integrations/buienradar/ +[cast docs]: /integrations/cast/ +[climacell docs]: /integrations/climacell/ +[climate docs]: /integrations/climate/ +[cloud docs]: /integrations/cloud/ +[command_line docs]: /integrations/command_line/ +[config docs]: /integrations/config/ +[cover docs]: /integrations/cover/ +[daikin docs]: /integrations/daikin/ +[deconz docs]: /integrations/deconz/ +[default_config docs]: /integrations/default_config/ +[demo docs]: /integrations/demo/ +[device_automation docs]: /integrations/device_automation/ +[device_tracker docs]: /integrations/device_tracker/ +[devolo_home_control docs]: /integrations/devolo_home_control/ +[dhcp docs]: /integrations/dhcp/ +[discovery docs]: /integrations/discovery/ +[dlna_dmr docs]: /integrations/dlna_dmr/ +[dsmr_reader docs]: /integrations/dsmr_reader/ +[ecobee docs]: /integrations/ecobee/ +[econet docs]: /integrations/econet/ +[elgato docs]: /integrations/elgato/ +[elkm1 docs]: /integrations/elkm1/ +[esphome docs]: /integrations/esphome/ +[evohome docs]: /integrations/evohome/ +[faa_delays docs]: /integrations/faa_delays/ +[fan docs]: /integrations/fan/ +[fibaro docs]: /integrations/fibaro/ +[flo docs]: /integrations/flo/ +[forked_daapd docs]: /integrations/forked_daapd/ +[freebox docs]: /integrations/freebox/ +[fritzbox_callmonitor docs]: /integrations/fritzbox_callmonitor/ +[frontend docs]: /integrations/frontend/ +[generic docs]: /integrations/generic/ +[generic_thermostat docs]: /integrations/generic_thermostat/ +[gios docs]: /integrations/gios/ +[glances docs]: /integrations/glances/ +[gogogate2 docs]: /integrations/gogogate2/ +[google_assistant docs]: /integrations/google_assistant/ +[graphite docs]: /integrations/graphite/ +[griddy docs]: /integrations/griddy/ +[hangouts docs]: /integrations/hangouts/ +[harmony docs]: /integrations/harmony/ +[hassio docs]: /integrations/hassio/ +[hdmi_cec docs]: /integrations/hdmi_cec/ +[history docs]: /integrations/history/ +[hive docs]: /integrations/hive/ +[homeassistant docs]: /integrations/homeassistant/ +[homekit docs]: /integrations/homekit/ +[homekit_controller docs]: /integrations/homekit_controller/ +[homematic docs]: /integrations/homematic/ +[homematicip_cloud docs]: /integrations/homematicip_cloud/ +[homepluscontrol docs]: /integrations/homepluscontrol/ +[http docs]: /integrations/http/ +[hue docs]: /integrations/hue/ +[huisbaasje docs]: /integrations/huisbaasje/ +[humidifier docs]: /integrations/humidifier/ +[hyperion docs]: /integrations/hyperion/ +[icloud docs]: /integrations/icloud/ +[incomfort docs]: /integrations/incomfort/ +[intesishome docs]: /integrations/intesishome/ +[izone docs]: /integrations/izone/ +[keenetic_ndms2 docs]: /integrations/keenetic_ndms2/ +[kmtronic docs]: /integrations/kmtronic/ +[knx docs]: /integrations/knx/ +[kodi docs]: /integrations/kodi/ +[konnected docs]: /integrations/konnected/ +[kulersky docs]: /integrations/kulersky/ +[lacrosse docs]: /integrations/lacrosse/ +[lastfm docs]: /integrations/lastfm/ +[lcn docs]: /integrations/lcn/ +[lg_soundbar docs]: /integrations/lg_soundbar/ +[lifx_legacy docs]: /integrations/lifx_legacy/ +[light docs]: /integrations/light/ +[litterrobot docs]: /integrations/litterrobot/ +[lock docs]: /integrations/lock/ +[logbook docs]: /integrations/logbook/ +[logger docs]: /integrations/logger/ +[luci docs]: /integrations/luci/ +[lutron_caseta docs]: /integrations/lutron_caseta/ +[lyric docs]: /integrations/lyric/ +[matrix docs]: /integrations/matrix/ +[maxcube docs]: /integrations/maxcube/ +[mazda docs]: /integrations/mazda/ +[mcp23017 docs]: /integrations/mcp23017/ +[media_extractor docs]: /integrations/media_extractor/ +[media_player docs]: /integrations/media_player/ +[meteo_france docs]: /integrations/meteo_france/ +[minecraft_server docs]: /integrations/minecraft_server/ +[mobile_app docs]: /integrations/mobile_app/ +[modbus docs]: /integrations/modbus/ +[motion_blinds docs]: /integrations/motion_blinds/ +[mqtt docs]: /integrations/mqtt/ +[mqtt_room docs]: /integrations/mqtt_room/ +[mychevy docs]: /integrations/mychevy/ +[mysensors docs]: /integrations/mysensors/ +[nanoleaf docs]: /integrations/nanoleaf/ +[neato docs]: /integrations/neato/ +[nest docs]: /integrations/nest/ +[netatmo docs]: /integrations/netatmo/ +[notify_events docs]: /integrations/notify_events/ +[numato docs]: /integrations/numato/ +[nut docs]: /integrations/nut/ +[octoprint docs]: /integrations/octoprint/ +[omnilogic docs]: /integrations/omnilogic/ +[onboarding docs]: /integrations/onboarding/ +[onvif docs]: /integrations/onvif/ +[opentherm_gw docs]: /integrations/opentherm_gw/ +[openweathermap docs]: /integrations/openweathermap/ +[panasonic_viera docs]: /integrations/panasonic_viera/ +[philips_js docs]: /integrations/philips_js/ +[pi_hole docs]: /integrations/pi_hole/ +[ping docs]: /integrations/ping/ +[plaato docs]: /integrations/plaato/ +[plex docs]: /integrations/plex/ +[point docs]: /integrations/point/ +[prometheus docs]: /integrations/prometheus/ +[prowl docs]: /integrations/prowl/ +[qnap docs]: /integrations/qnap/ +[recorder docs]: /integrations/recorder/ +[remote docs]: /integrations/remote/ +[rest docs]: /integrations/rest/ +[rflink docs]: /integrations/rflink/ +[roku docs]: /integrations/roku/ +[roomba docs]: /integrations/roomba/ +[rpi_gpio docs]: /integrations/rpi_gpio/ +[screenlogic docs]: /integrations/screenlogic/ +[script docs]: /integrations/script/ +[search docs]: /integrations/search/ +[sendgrid docs]: /integrations/sendgrid/ +[sensor docs]: /integrations/sensor/ +[sentry docs]: /integrations/sentry/ +[seventeentrack docs]: /integrations/seventeentrack/ +[shelly docs]: /integrations/shelly/ +[smarttub docs]: /integrations/smarttub/ +[snapcast docs]: /integrations/snapcast/ +[solaredge docs]: /integrations/solaredge/ +[solax docs]: /integrations/solax/ +[somfy_mylink docs]: /integrations/somfy_mylink/ +[spotify docs]: /integrations/spotify/ +[squeezebox docs]: /integrations/squeezebox/ +[ssdp docs]: /integrations/ssdp/ +[stream docs]: /integrations/stream/ +[subaru docs]: /integrations/subaru/ +[synology_dsm docs]: /integrations/synology_dsm/ +[tado docs]: /integrations/tado/ +[tasmota docs]: /integrations/tasmota/ +[tellduslive docs]: /integrations/tellduslive/ +[template docs]: /integrations/template/ +[tesla docs]: /integrations/tesla/ +[thethingsnetwork docs]: /integrations/thethingsnetwork/ +[tibber docs]: /integrations/tibber/ +[tod docs]: /integrations/tod/ +[todoist docs]: /integrations/todoist/ +[toon docs]: /integrations/toon/ +[tplink docs]: /integrations/tplink/ +[trace docs]: /integrations/trace/ +[tradfri docs]: /integrations/tradfri/ +[trigger docs]: /integrations/trigger/ +[twentemilieu docs]: /integrations/twentemilieu/ +[twitter docs]: /integrations/twitter/ +[unifi docs]: /integrations/unifi/ +[universal docs]: /integrations/universal/ +[upcloud docs]: /integrations/upcloud/ +[updater docs]: /integrations/updater/ +[upnp docs]: /integrations/upnp/ +[uvc docs]: /integrations/uvc/ +[vacuum docs]: /integrations/vacuum/ +[vera docs]: /integrations/vera/ +[verisure docs]: /integrations/verisure/ +[version docs]: /integrations/version/ +[vesync docs]: /integrations/vesync/ +[vicare docs]: /integrations/vicare/ +[vlc_telnet docs]: /integrations/vlc_telnet/ +[wake_on_lan docs]: /integrations/wake_on_lan/ +[water_heater docs]: /integrations/water_heater/ +[webostv docs]: /integrations/webostv/ +[websocket_api docs]: /integrations/websocket_api/ +[wemo docs]: /integrations/wemo/ +[withings docs]: /integrations/withings/ +[wled docs]: /integrations/wled/ +[workday docs]: /integrations/workday/ +[wunderground docs]: /integrations/wunderground/ +[xbox docs]: /integrations/xbox/ +[xiaomi_miio docs]: /integrations/xiaomi_miio/ +[xmpp docs]: /integrations/xmpp/ +[yeelight docs]: /integrations/yeelight/ +[zeroconf docs]: /integrations/zeroconf/ +[zerproc docs]: /integrations/zerproc/ +[zha docs]: /integrations/zha/ +[zwave docs]: /integrations/zwave/ +[zwave_js docs]: /integrations/zwave_js/ \ No newline at end of file diff --git a/source/images/blog/2021-04/social.png b/source/images/blog/2021-04/social.png new file mode 100644 index 0000000000000000000000000000000000000000..64020144d360ddcf0a110eabb223dc1f05fef51b GIT binary patch literal 99174 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 z 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 z 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 F{|}(<;Hv-t literal 0 HcmV?d00001 From d48586252190249ec5ecf54cc4c0f79f94629be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Thu, 1 Apr 2021 01:58:58 +0200 Subject: [PATCH 77/90] Remove analytics from default_config (#17216) --- source/_integrations/analytics.markdown | 8 -------- source/_integrations/default_config.markdown | 1 - 2 files changed, 9 deletions(-) diff --git a/source/_integrations/analytics.markdown b/source/_integrations/analytics.markdown index c8068b5dba3..e0e2f040047 100644 --- a/source/_integrations/analytics.markdown +++ b/source/_integrations/analytics.markdown @@ -20,14 +20,6 @@ When enabled the integration will send data 15 minutes after each start, and eve The collected data is available to the public at -## Configuration - -This integration is by default enabled, unless you've disabled or removed the [`default_config:`](/integrations/default_config/) line from your configuration. If that is the case, the following example shows you how to enable this integration manually, just enabling the integration will **not** make it sent analytics: - -```yaml -analytics: -``` - ## Basic analytics This includes: diff --git a/source/_integrations/default_config.markdown b/source/_integrations/default_config.markdown index db47d97d153..70aa848466f 100644 --- a/source/_integrations/default_config.markdown +++ b/source/_integrations/default_config.markdown @@ -11,7 +11,6 @@ ha_quality_scale: internal This integration is a meta-component and configures a default set of integrations for Home Assistant to load. The integrations that will be loaded are: -- [Analytics](/integrations/analytics) (`analytics`) - [Automation](/integrations/automation/) (`automation`) - [Home Assistant Cloud](/integrations/cloud/) (`cloud`) - [Configuration](/integrations/config/) (`config`) From 8ed686c19ad867c72d064db87047b11d4d07c89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Fri, 2 Apr 2021 14:41:48 +0200 Subject: [PATCH 78/90] Country note (#17232) --- source/_integrations/analytics.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/_integrations/analytics.markdown b/source/_integrations/analytics.markdown index e0e2f040047..7cdb94528d6 100644 --- a/source/_integrations/analytics.markdown +++ b/source/_integrations/analytics.markdown @@ -143,10 +143,10 @@ The data is stored in CloudFlare's KV (Key-Value) store for the [Receiver](#rece This is an example of how the information is stored: {% configuration_basic %} "huuid:12a3456bc78d90123ef4567g789012h3": - description: "{'version': '2021.4.0', 'installation_type': 'Home Assistant OS'}" + description: "{'version': '2021.4.0', 'installation_type': 'Home Assistant OS', 'country': 'NO'}" {% endconfiguration_basic %} -Like all other websites you visit, the IP address and client information that sent the request will be visible to the remote server, this, however, is not stored by us (you are more than welcome to inspect [the code that receives the data](https://github.com/home-assistant/analytics.home-assistant.io)), CloudFlare will keep a log of all interactions, [see their privacy policy for more details about that](https://www.cloudflare.com/privacypolicy/) +Like all other websites you visit, the IP address and client information that sent the request will be visible to the remote server, other than the country-code of origin for the request nothing else is stored by us (you are more than welcome to inspect [the code that receives the data](https://github.com/home-assistant/analytics.home-assistant.io)), CloudFlare will keep a log of all interactions, [see their privacy policy for more details about that](https://www.cloudflare.com/privacypolicy/) The data will be used to display the information on and to analyze how users are using Home Assistant. This allows for workload prioritizing to focus resources on improving the areas that are most important to our users. From 4ed78dab24cb8238e3e8c9a20a4759e01fbdaf2a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 4 Apr 2021 04:01:43 -0700 Subject: [PATCH 79/90] Update docs for trigger-based template sensors. (#17243) --- source/_integrations/template.markdown | 51 +++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/source/_integrations/template.markdown b/source/_integrations/template.markdown index 369304943da..ec205c8bcb9 100644 --- a/source/_integrations/template.markdown +++ b/source/_integrations/template.markdown @@ -25,7 +25,7 @@ ha_platforms: The `template` integration allows creating entities which derive their values from other entities. This is done by defining [templates](/docs/configuration/templating/) for each property of an entity, like the name or the state. Entities are updated automatically whenever a value that a template relies on changes. -For sensors it's also possible to derive the state from [automation triggers](#configuration-for-trigger-based-template-sensors). +For template sensors it's also possible to derive the state from [automation triggers](#configuration-for-trigger-based-template-sensors). Available template platforms: @@ -152,6 +152,8 @@ curl --header "Content-Type: application/json" \ http://homeassistant.local:8123/api/webhook/my-super-secret-webhook-id ``` +

    Configuration under the template: key uses a different format compared to the platform configuration.

    + {% configuration %} trigger: description: The trigger configuration for this entity. [See trigger documentation](/docs/automation/trigger) @@ -162,9 +164,54 @@ unique_id: required: false type: string sensor: - description: Map of your sensors to create from the trigger data. For available keys, see [configuration variables](#configuration-variables) above. + description: List of sensors to create from the trigger data. required: true type: map + keys: + state: + description: Defines a template to get the state of the sensor. + required: true + type: template + name: + description: Defines a template to get the name of the sensor. + required: false + type: template + unique_id: + description: An ID that uniquely identifies this sensor. Will be combined with the unique ID of the configuration block if available. + required: false + type: string + unit_of_measurement: + description: "Defines the units of measurement of the sensor, if any. This will also influence the graphical presentation in the history visualization as a continuous value. Sensors with missing `unit_of_measurement` are showing as discrete values." + required: false + type: string + default: None + icon: + description: Defines a template for the icon of the sensor. + required: false + type: template + picture: + description: Defines a template for the entity picture of the sensor. + required: false + type: template + attributes: + description: Defines templates for attributes of the sensor. + required: false + type: map + keys: + "attribute: template": + description: The attribute and corresponding template. + required: true + type: template + availability: + description: Defines a template to get the `available` state of the component. If the template returns `true`, the device is `available`. If the template returns any other value, the device will be `unavailable`. If not configured, the component will always be `available`. + required: false + type: template + default: true + device_class: + description: Sets the class of the device, changing the device state and icon that is displayed on the UI (see below). It does not set the `unit_of_measurement`. + required: false + type: device_class + default: None {% endconfiguration %}

    It's currently only possible to define trigger-based entities via the top-level configuration. These entities are not yet included when reloading template entities.

    From f4fda64a0de2bf49ce5b1f4b0c38a45715013b06 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Sun, 4 Apr 2021 13:16:48 +0200 Subject: [PATCH 80/90] Fix documentation for new feature mqtt command templates (#17252) --- source/_integrations/fan.mqtt.markdown | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/_integrations/fan.mqtt.markdown b/source/_integrations/fan.mqtt.markdown index 3650ba6dead..ac49e346819 100644 --- a/source/_integrations/fan.mqtt.markdown +++ b/source/_integrations/fan.mqtt.markdown @@ -282,6 +282,8 @@ fan: speed_range_max: 100 ``` +{% raw %}} + This example demonstrates how to use command templates with JSON output. ```yaml @@ -295,7 +297,7 @@ fan: oscillation_command_topic: "bedroom_fan/oscillation/set" oscillation_command_template: "{ oscillation: '{{ value }}'}" percentage_command_topic: "bedroom_fan/speed/percentage" - percentage_command_template: "{ percentage: {{ value }}}" + percentage_command_template: "{ percentage: '{{ value }}'}" preset_mode_command_topic: "bedroom_fan/speed/preset_mode" preset_mode_command_template: "{ preset_mode: '{{ value }}'}" preset_modes: @@ -305,3 +307,5 @@ fan: - "eco" - "breeze" ``` + +{% endraw %} \ No newline at end of file From ff0f0489d7ce93e0f12bb747cee5edd0f8754fd3 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 4 Apr 2021 04:15:59 -0700 Subject: [PATCH 81/90] Reword analytics (#17260) Co-authored-by: Martin Hjelmare Co-authored-by: Franck Nijhof --- source/_integrations/analytics.markdown | 65 ++++++++++++------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/source/_integrations/analytics.markdown b/source/_integrations/analytics.markdown index 7cdb94528d6..a9be3a15aac 100644 --- a/source/_integrations/analytics.markdown +++ b/source/_integrations/analytics.markdown @@ -12,26 +12,29 @@ ha_codeowners: ha_domain: analytics --- -The Analytics integration will collect information about the running Home Assistant instance and its environment. The information sent depends on what sections you enable in the integration, by default nothing is enabled. The different sections can be controlled in the UI under **{% my general title="Configuration >> General" %}**. +Home Assistant allows users to share their usage data via the analytics integration. The aggregated data is available at . It is used to influence Home Assistant development priorities and to convince manufacturers to add local control and privacy-focused features. + +## Data Collection + +The information sent depends on what you opt-in to. You can opt-in during onboarding and by going to **{% my general title="Configuration >> General" %}**. **{% my general badge %}** -When enabled the integration will send data 15 minutes after each start, and every 24h after startup. When the data is sent the full payload will be printed to your log. +When enabled, data will be sent 15 minutes after each start, and every 24h after startup. Sent data is printed to your log. -The collected data is available to the public at - -## Basic analytics +### Basic analytics This includes: -- The UUID of your system -- The version of your system -- The installation type of your system +- Unique identifier for your system (to ensure each installation is counted once) +- Home Assistant version +- Home Assistant installation type +- Your country (derived server-side from your IP-address) -If your system includes the Supervisor this will also contain: +If your system includes the Supervisor, this will also contain: -- A boolean that indicates if the system is supported -- A boolean that indicates if the system is healthy +- If your installation is supported +- If your installation is healthy {% details Example payload %} @@ -49,20 +52,21 @@ If your system includes the Supervisor this will also contain: {% enddetails %} -## Usage analytics +### Usage analytics -You need to enable [basic analytics](#basic-analytics) to be able to enable this. +_Requires basic analytics to be enabled._ This includes: - The names of all your integrations -If your system include the Supervisor this will also contain: +If your system includes the Supervisor, this will also contain: -- The name of all installed add-ons -- The version of all installed add-ons -- The state of protection mode of all installed add-ons -- The state of the auto update toggle of all installed add-ons +- For each add-on + - Name + - Version + - If protection mode is enabled + - If auto update is enabled {% details Example payload %} @@ -89,9 +93,9 @@ If your system include the Supervisor this will also contain: {% enddetails %} -## Statistics +### Statistics -You need to enable [basic analytics](#basic-analytics) to be able to enable this. +_Requires basic analytics to be enabled._ This includes: @@ -100,7 +104,7 @@ This includes: - Number of entities - Number of automations -If your system include the Supervisor this will also contain: +If your system includes the Supervisor, this will also contain: - Number of installed add-ons @@ -125,20 +129,19 @@ If your system include the Supervisor this will also contain: {% enddetails %} -## Diagnostics +### Diagnostics -This is not sent to the same [Receiver](#receiver) as the rest of the information enabled with this integration. Crash reports are sent to [Sentry](https://sentry.io/welcome/). This data will not be made public and will only be available to a few core developers. +If enabled, a crash report will be collected when an unexpected error occurs and uploaded to [Sentry](https://sentry.io). These reports will help fix bugs and improve performance and stability. -For now, this is only being done for events inside the Supervisor if your system has that. If this changes to include other parts of the ecosystem it will be mentioned in the release notes and the documentation here will be updated. +Crash reports are only visible to the Home Assistant Core developers. This feature is currently limited to the Supervisor. -## Receiver +## Data storage & processing -The receiver that the payloads are sent to is running as a [CloudFlare Worker](https://workers.cloudflare.com/) and the code for that can be inspected in the [home-assistant/analytics repository](https://github.com/home-assistant/analytics.home-assistant.io). +All data is received and processed by the Home Assistant Analytics Receiver ([source](https://github.com/home-assistant/analytics.home-assistant.io)). -## Storage and usage +When your installation sends a payload, that payload includes a unique identifier. This identifier is used to make sure that your installation is only counted once. -When your installation sends a payload, that payload includes a unique identifier, this identifier is used to make sure that future payload updates, only change information from your installation. -The data is stored in CloudFlare's KV (Key-Value) store for the [Receiver](#receiver), and will be stored for a maximum of 60 days since the last update. +Your data is securely stored in [CloudFlare's Key-Value store](https://www.cloudflare.com/products/workers-kv/). It will be stored for a maximum of 60 days since the last update. Only aggregated data is made publicly available. This is an example of how the information is stored: {% configuration_basic %} @@ -146,7 +149,3 @@ This is an example of how the information is stored: description: "{'version': '2021.4.0', 'installation_type': 'Home Assistant OS', 'country': 'NO'}" {% endconfiguration_basic %} - -Like all other websites you visit, the IP address and client information that sent the request will be visible to the remote server, other than the country-code of origin for the request nothing else is stored by us (you are more than welcome to inspect [the code that receives the data](https://github.com/home-assistant/analytics.home-assistant.io)), CloudFlare will keep a log of all interactions, [see their privacy policy for more details about that](https://www.cloudflare.com/privacypolicy/) - -The data will be used to display the information on and to analyze how users are using Home Assistant. This allows for workload prioritizing to focus resources on improving the areas that are most important to our users. From 1f93ee1e637e58d9214f7c8004e16d3a4a0e8aa2 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Mon, 5 Apr 2021 16:06:31 -0400 Subject: [PATCH 82/90] Add note about breaking changes to zwave_js section of release notes (#17292) Co-authored-by: Franck Nijhof --- source/_posts/2021-04-07-release-20214.markdown | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/_posts/2021-04-07-release-20214.markdown b/source/_posts/2021-04-07-release-20214.markdown index 23d2e531812..ac0995e8421 100644 --- a/source/_posts/2021-04-07-release-20214.markdown +++ b/source/_posts/2021-04-07-release-20214.markdown @@ -137,6 +137,8 @@ Furthermore two new services are introduced: - `zwave_js.bulk_set_partial_config_parameters` - `zwave_js.set_value` +There are breaking changes in the Z-Wave JS integration that could affect your existing automations. Be sure to read the [breaking changes](#breaking-changes) section for more info. + TODO: - Add more text to this - Add screenshot @@ -2394,4 +2396,4 @@ The following integrations are no longer available as of this release: [zerproc docs]: /integrations/zerproc/ [zha docs]: /integrations/zha/ [zwave docs]: /integrations/zwave/ -[zwave_js docs]: /integrations/zwave_js/ \ No newline at end of file +[zwave_js docs]: /integrations/zwave_js/ From 58cbf8aee8444f236aacfd4f7dced06a2d43ff3c Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 7 Apr 2021 08:09:27 -0500 Subject: [PATCH 83/90] Add newly supported bulbs for tplink (#17125) Co-authored-by: Franck Nijhof --- source/_integrations/tplink.markdown | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/_integrations/tplink.markdown b/source/_integrations/tplink.markdown index 1162ab210c6..f34bd74de88 100644 --- a/source/_integrations/tplink.markdown +++ b/source/_integrations/tplink.markdown @@ -59,6 +59,8 @@ Plugs are type `switch` when autodiscovery has been disabled. ### Bulbs +Other bulbs may also work, but with limited color temperatures. If you find a bulb isn't reaching the full-color temperature boundaries, submit a bug report. + - LB100 - LB110 - LB120 @@ -66,7 +68,10 @@ Plugs are type `switch` when autodiscovery has been disabled. - LB230 - KL110 - KL120 +- KL125 - KL130 +- KB130 +- KL430 ## Configuration From aff1b9aa2d4a5983e12f480365f290cbfb5925e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Wed, 7 Apr 2021 03:27:44 +0200 Subject: [PATCH 84/90] Change uuid (#17307) --- source/_integrations/analytics.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/_integrations/analytics.markdown b/source/_integrations/analytics.markdown index a9be3a15aac..ea4a1828a8b 100644 --- a/source/_integrations/analytics.markdown +++ b/source/_integrations/analytics.markdown @@ -40,7 +40,7 @@ If your system includes the Supervisor, this will also contain: ```json { - "huuid": "12a3456bc78d90123ef4567g789012h3", + "uuid": "12a3456bc78d90123ef4567g789012h3", "version": "2021.4.0", "installation_type": "Home Assistant OS", "supervisor": { @@ -72,7 +72,7 @@ If your system includes the Supervisor, this will also contain: ```json { - "huuid": "12a3456bc78d90123ef4567g789012h3", + "uuid": "12a3456bc78d90123ef4567g789012h3", "version": "2021.4.0", "installation_type": "Home Assistant OS", "supervisor": { @@ -112,7 +112,7 @@ If your system includes the Supervisor, this will also contain: ```json { - "huuid": "12a3456bc78d90123ef4567g789012h3", + "uuid": "12a3456bc78d90123ef4567g789012h3", "version": "2021.4.0", "installation_type": "Home Assistant OS", "supervisor": { @@ -145,7 +145,7 @@ Your data is securely stored in [CloudFlare's Key-Value store](https://www.cloud This is an example of how the information is stored: {% configuration_basic %} -"huuid:12a3456bc78d90123ef4567g789012h3": +"uuid:12a3456bc78d90123ef4567g789012h3": description: "{'version': '2021.4.0', 'installation_type': 'Home Assistant OS', 'country': 'NO'}" {% endconfiguration_basic %} From 2646fb23602f6a55a2a5955400f69ec8d1d3721f Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Wed, 7 Apr 2021 17:55:33 +0200 Subject: [PATCH 85/90] Update release notes for 2021.4 --- .../_posts/2021-04-07-release-20214.markdown | 468 ++++++++++++------ source/images/blog/2021-04/analytics.png | Bin 0 -> 80424 bytes .../blog/2021-04/automation-tracing.png | Bin 0 -> 78974 bytes .../images/blog/2021-04/enable-analytics.png | Bin 0 -> 59201 bytes source/images/blog/2021-04/filters.png | Bin 0 -> 67999 bytes source/images/blog/2021-04/number-format.png | Bin 0 -> 70553 bytes .../images/blog/2021-04/scripts-selectors.png | Bin 0 -> 93463 bytes source/images/blog/2021-04/undefined.png | Bin 0 -> 37013 bytes source/images/blog/2021-04/zwave-device.png | Bin 0 -> 81062 bytes 9 files changed, 317 insertions(+), 151 deletions(-) create mode 100644 source/images/blog/2021-04/analytics.png create mode 100644 source/images/blog/2021-04/automation-tracing.png create mode 100644 source/images/blog/2021-04/enable-analytics.png create mode 100644 source/images/blog/2021-04/filters.png create mode 100644 source/images/blog/2021-04/number-format.png create mode 100644 source/images/blog/2021-04/scripts-selectors.png create mode 100644 source/images/blog/2021-04/undefined.png create mode 100644 source/images/blog/2021-04/zwave-device.png diff --git a/source/_posts/2021-04-07-release-20214.markdown b/source/_posts/2021-04-07-release-20214.markdown index ac0995e8421..a31e69d2868 100644 --- a/source/_posts/2021-04-07-release-20214.markdown +++ b/source/_posts/2021-04-07-release-20214.markdown @@ -1,8 +1,8 @@ --- layout: post -title: "2021.4: For our advanced users ❤️ (Beta release notes)" -description: "The beta release notes for the upcoming Home Assistant Core 2021.4 release." -date: 2021-3-31 00:00:00 +title: "2021.4: For our advanced users ❤️" +description: "Debug and trace your automations runs! Home Assistant Analytics! Trigger based template! and much more..." +date: 2021-04-07 00:00:00 date_formatted: "April 7, 2021" author: Franck Nijhof author_twitter: frenck @@ -16,27 +16,23 @@ feedback: true -These are the beta release notes for Home Assistant Core 2021.4 (and is thus a -work in progress). +Survived April fools day? I assure you, this April release is no joke! -If you encounter any issues with the beta release, please report them on GitHub: +This release is dedicated to our more advanced user base, as it is packed with +some really advanced features and enhancements our more experienced users will +love. Ready to debug your automations? Yeah... -- Issues with integrations, automations and such (Core related):
    - -- Issues with the frontend/Lovelace:
    - -- Issues with the Supervisor:
    - -- Issues with the documentation:
    - +Not that advanced of a user? I'm sure there is something in here for you to +look forward to as well. -Please be sure to include the beta version you are running in the issue -description (not title), so we can classify your issue correctly. +Enjoy the release! -Issues introduced in the beta are processed with priority. +../Frenck +- [Database upgrades, please be patient](#database-upgrades-please-be-patient) - [Automation debugging](#automation-debugging) - [Home Assistant Analytics](#home-assistant-analytics) +- [Warnings for undefined variables in Templates](#warnings-for-undefined-variables-in-templates) - [Filtering automations, scripts and scenes](#filtering-automations-scripts-and-scenes) - [Z-Wave JS update](#z-wave-js-update) - [Trigger-based template sensors](#trigger-based-template-sensors) @@ -50,107 +46,202 @@ Issues introduced in the beta are processed with priority. - [Farewell to the following](#farewell-to-the-following) - [All changes](#all-changes) +## Database upgrades, please be patient + +This release contains database migrations, meaning that the format of how your +history is stored is changing. This migration is automatically performed after +upgrading and takes a bit of time. The time it takes depends on how much history +you have stored and how fast your system is. + +Please be patient when upgrading to this release. + ## Automation debugging Wait, why didn't that light turn on? Why isn't the thermostat adjusted? Why is this automation not working? What is going on here?! This is a haunted house!?! -Sounds familiar? I'm sure we all had these moment, but are you ready for this? +Sounds familiar? I'm sure we all had these moments, but are you ready for this? We can now debug automations! - +

    +Screenshot showing the automation trace of a previously ran automation +Screenshot showing the automation trace of a previously ran automation. +

    -View details on previous automation runs, and see details on each step to -explore what happened. +The above screenshot shows a previous run of an automation. The automation +is displayed in the form of an interactive graph. You can see which path it took +and each step of the automation can be click and viewed in detail on what +happened. It traces the complete run of an automation run. -TODO: -- Add screenshots / recordings -- Thank everybody involved in this, Erik, Paulus, Bram, Thomas this is awesome! -- More body to the paragraph +If an automation didn't run as it should, this will allows you to debug and +understand why it ran the way it did. - +This extremely advanced and super useful feature is thanks to the hard work +of [@emontnemery] who, build the backend for this. The beautiful graphing was +made by [@thomasloven], and all the frontend work by [@balloob] & [@bramkragten]. +Finally, all the (beta) testers that provided traces samples that helped +squash bugs. Thanks all! + +Got questions about this feature? Want to see it in action? Be sure to tune in +to the 2021.4 release party stream later today! + +
    + +
    + +[@thomasloven]: https://github.com/thomasloven ## Home Assistant Analytics Now don't be scared by the title! -Today we introduce, Home Assistant Analytics. Opt-in, privacy aware, public +Today we introduce: Home Assistant Analytics. Opt-in, privacy-aware, public and open source. Just as it all should be for our project. -Ludeeus did an amazing job writing this new integration. You decide if you turn -it on or not; however, we guarantee its privacy aware. Doubt it? Review it! +[@ludeeus] did a fantastic job writing this new integration. You decide if you +turn it on or not; however, we guarantee its privacy-aware. Doubt it? Review it! Everything is open source! -Not open enough for you? Well, maybe you want to view the public result: +Not open enough for you? We are publishing the result for everybody to see: + +

    +Screenshot of the Home Assistant Analytics website +Screenshot of the Home Assistant Analytics website. +

    + +Well, maybe you want to view the public result yourself: So why do we do this? Well, it helps the project and all contributors to -see things like: Most used integrations. This can greatly help with improving -project priorities. +see things like: Most used integrations. This can significantly help with +improving project priorities. It also helps to convince manufacturers to work +with Home Assistant, add local control and privacy-focused features. -"But the updater did this already, right?" Yes, well, thing has been broken -actually. So while we had some data, it was barely usable (actually not useable -at all). Instead of fixing the updater, we now have a better solution that -better matches our project goals. The update still exists, it now just does one -single thing: Showing if an update is available. +"But the updater did this already, right?" Yes, well, the updater has actually +been broken. So while we had some data, it was barely usable (actually not +useable at all). Instead of fixing the updater, we now have a better solution +that better matches our project goals. The updater still exists; it now just +does one single thing: Showing if an update is available. -TODO: -- Improve text -- Add screenshot or embed analytics? -- Instructions on how to activate? -- Link to documentation +Want to help the project out? Please enable Home Assistant Analytics. We +would be very grateful! + +You can find the settings in the {% my general title="general configuration options" %}, +or click the My Home Assistant button below to go directly to it. + +{% my general badge %} + +

    +Screenshot of the Home Assistant Analytics options +Screenshot of the Home Assistant Analytics options, you control the amount of +data you share. +

    + +For more information on how this all works and what data is shared, +[check out our documentation](/integrations/analytics). + +Thanks for sharing already! ❤️ + +## Warnings for undefined variables in Templates + +This feature is really cool. While technically a small improvement, it is a +change that can impact you (as in "breaking"), but also, will greatly help you! + +So imaging this little template: `{% raw %}{{ my_variable }}{% endraw %}` + +Previously, if `my_variable` would not exist in the template or system as a +variable, Home Assistant would just ignore it and skip over it. + +While this can be convenient, it can become problematic when it was misspelled +or referring to a variable that doesn't exist at all. For example, if you +would have mistyped it: `{% raw %}{{ my_varaible }}{% endraw %}`, you would +never know something is wrong, unless you spotted it. + +As of today, Home Assistant will tell you this, using a warning in the logs! + +

    +Screenshot of undefined variable warning log +Screenshot of undefined variable warning log. +

    + +This helps to find templates that behave unexpectedly because the variable +you thought was there, isn't. It is quite possible you get a bunch +of warnings after upgrading to this release. Fixing those warnings, really helps +to improve your setup. + +So, what if a viable isn't always there, but I still want to use it? Well, +you can give it a default, for example: +`{% raw %}{{ my_variable | default }}{% endraw %}`. Or even an default value +(10 in this example): `{% raw %}{{ my_variable | default(10) }}{% endraw %}`. + +Please note that these are just warnings for now. We plan to replace the warning +with an error as of Home Assistant 2021.10 (in October). ## Filtering automations, scripts and scenes Categorizing things like automations, is definitely one of the most requested -things in our history. This became clear again during last years month of -what the heck and in various issues/discussions/feature requests. +things in our history. This became clear again during last year's month of what +the heck and various issues/discussions/feature requests. Suggestions for labels, folders, and many more have been created. However, we already have some great categorizing features in Home Assistant itself: -Devices & Areas +Devices, Areas & Entities. + +

    +Screenshot of filtering automations by the living room area +Screenshot of filtering automations by living room area. +

    As of today, you can filter your automations, scripts and scenes based on -the device or area they are put in, or affect. Not only can you now -show show the automations that are used in your living room area, but you can -also filter automations with just the ones that touch your thermostat. - -TODO: -- Add screenshot -- Improve text +the area they are put in, or the device/entity they affect. You now show the +automations used in your living room area, but you can also filter automations +with just the ones that touch your thermostat. ## Z-Wave JS update -You can now configure each device. When you view a device in the Home -Assistant frontend, you can click on "CONFIGURE DEVICE" to manage and adjust -device (node) specific configuration parameters for the selected device. +So before we talk about The nice new things in Z-Wave JS, there are breaking +changes in this release for the Z-Wave JS integration that could affect your +existing automations. Be sure to read the [breaking changes](#breaking-changes) +section for more info. -Furthermore two new services are introduced: +Alright, now the fun stuff! You can now configure each Z-Wave device straight +from within Home Assistant. When you view a device in the Home Assistant +frontend, you can click on "CONFIGURE DEVICE" button that is shown on each +device page. This allows you to manage and adjust device (node) specific +configuration parameters for the selected device. -- `zwave_js.bulk_set_partial_config_parameters` -- `zwave_js.set_value` +

    +Screenshot of configuring a Z-Wave device from within Home Assistant +Screenshot of configuring a Z-Wave device from within Home Assistant. +

    -There are breaking changes in the Z-Wave JS integration that could affect your existing automations. Be sure to read the [breaking changes](#breaking-changes) section for more info. +Furthermore two new, advanced, services are introduced: -TODO: -- Add more text to this -- Add screenshot -- Missing Z-Wave updates? +- {% my developer_call_service service="zwave_js.set_value" %}, a service that + is capable of setting set a value on a Z-Wave device directly, bypassing + Home Assistant. +- {% my developer_call_service service="zwave_js.bulk_set_partial_config_parameters" %}, + a service that will allow you to set configuration parameters in bulk. ## Trigger-based template sensors -This release adds initial support for pretty advanced new feature, that can -be really helpful. Sensors, that are updated based on triggers and the -data that comes with it. +This release adds initial support for a pretty advanced new, helpful feature. +Template sensors, that are updated based on triggers and the data that comes +with it. + +Whenever the trigger fires, the template sensor will re-render and it will +have access to the trigger data in the templates. This feature is a great way +to create data based on webhook data, or have sensors be updated based on a +time schedule. + +See, for example, this these two template sensors that update based on a single +webhook trigger using data pushed into the webhook: {% raw %} + ```yaml # Example configuration entry template: @@ -175,100 +266,66 @@ curl --header "Content-Type: application/json" \ http://homeassistant.local:8123/api/webhook/my-super-secret-webhook-id ``` -TODO: -- Extend story -- Clean up/simplify example -- Note on sensor only at this point, hopefully more soon! +It is not just webhooks! Any trigger that you can use in automations, can be +used to update these types of template sensors. + +For this release, it only works for sensors; other platforms are supported yet. + +Please note: that these new template sensors are configured under the `template:` +key in the configuration and is using a new configuration format and keys. +For more information, [see the documentation](/integrations/template/#configuration-for-trigger-based-template-sensors). ## UI selectors for script fields You can now use UI Selectors for you scripts field parameters. This -brings UI capabilities to scripts. It works both in the dev tools -> services, -but also in the automation UI. +brings the same UI capabilities that Blueprint have to scripts. This allow for +creating advanced scripts that you can later easily reuse in your UI +(even in UI automation). -Example: -Selectors: -More extensive service description example: +

    +Screenshot of scripts using selects in its fields +Screenshot of scripts using selects in its fields. +

    -TODO: -- Improve documentation. I noticed when linking this, that documentation around - fields is low. -- Screenshot -- More text -- Example? +For more details on these new field configuration option, see the +[scripts documentation](/integrations/script) ## Other noteworthy changes There is much more juice in this release; here are some of the other noteworthy changes this release: -- Lorem ipsum, thanks to [@frenck]! ;) -- TODO with items from below. +- The Supervisor is now in the integrations dashboard, and provides entities + for all kinds of things! These entities are disabled by default, so head + over and see if there is anything to enable. Thanks [@raman325]! +- The develo Home Control ([@Shutgun]), Apple TV ([@bdraco]), August ([@bdraco]) + and MQTT ([@RadekHvizdos]) integrations can now suggest areas. +- You can now configure additional Google Cast devices by IP address via the + integrations options. This is helpful in case of mDNS issues. + Thanks [@emontnemery]! +- [@joshmcrty] added support for selecting the number formatting you like on + your profile! Awesome work! -To format, candidates from the backend: +

    +Screenshot of selecting the number format you prefer in your profile +Screenshot of selecting the number format you prefer. +

    -- Add Xiaomi Miio fan config flow ([@starkillerOG] - [#46866]) ([xiaomi_miio docs]) (breaking-change) -- Add remote control platform to Panasonic Viera ([@joogps] - [#42450]) ([panasonic_viera docs]) (new-platform) -- Add zeroconf discovery to Freebox ([@Quentame] - [#47045]) ([discovery docs]) ([freebox docs]) -- Add suggested_area support to devolo Home Control ([@Shutgun] - [#47063]) ([devolo_home_control docs]) -- Add hassio addon_update service and hassio config entry with addon and OS devices and entities ([@raman325] - [#46342]) ([hassio docs]) (new-platform) -- Add support for a list of known hosts to Google Cast ([@emontnemery] - [#47232]) ([cast docs]) -- Add remote control support to philips_js ([@elupus] - [#47249]) ([philips_js docs]) (new-platform) -- Add battery sensor for gogogate2 wireless door sensor ([@emontnemery] - [#47145]) ([gogogate2 docs]) (new-platform) -- Add services for izone airflow min/max ([@Nick-Adams-AU] - [#45727]) ([izone docs]) -- Add force_update to tasmota sensors ([@rlehfeld] - [#47052]) ([tasmota docs]) -- Add suggested_area support to Apple TV ([@bdraco] - [#47015]) ([apple_tv docs]) -- Add Tado weather support ([@Noltari] - [#44807]) ([tado docs]) (new-platform) -- Fix light brightness_step on multiple entities ([@emontnemery] - [#47746]) ([light docs]) -- Hoist mqtt name property and add icon support to MqttEntity ([@kristianheljas] - [#47165]) ([mqtt docs]) -- Add apply_filter attribute to recorder.purge service ([@cdce8p] - [#45826]) ([recorder docs]) -- Add HomeKit support for new CO / CO2 device class ([@iMicknl] - [#47737]) ([demo docs]) ([homekit docs]) -- Add device_info to Apple TV entities ([@postlund] - [#47837]) ([apple_tv docs]) -- Verisure: Remove JSONPath, unique IDs, small cleanups ([@frenck] - [#47870]) ([verisure docs]) -- Add suggested area support to august ([@bdraco] - [#47930]) ([august docs]) -- Support all Xiaomi Miio gateway switches ([@starkillerOG] - [#46657]) ([xiaomi_miio docs]) -- Add suggested_area to MQTT discovery ([@RadekHvizdos] - [#47903]) ([mqtt docs]) -- Add config flow to Verisure ([@frenck] - [#47880]) ([verisure docs]) (breaking-change) -- Move Verisure services to entity services ([@frenck] - [#47905]) ([verisure docs]) (breaking-change) -- Add devices to Verisure integration ([@frenck] - [#47913]) ([verisure docs]) -- Add reauthentication to Verisure ([@frenck] - [#47972]) ([verisure docs]) -- Add support for light color modes ([@emontnemery] - [#47720]) ([kulersky docs]) ([light docs]) ([yeelight docs]) ([zerproc docs]) -- Add device classes to Verisure sensors ([@frenck] - [#47990]) ([verisure docs]) -- Add definitions for grouping media players ([@klada] - [#41193]) ([media_player docs]) -- Add Opentherm Gateway current and setpoint precision ([@Martidjen] - [#47484]) ([opentherm_gw docs]) -- Warn on undefined variables in templates ([@emontnemery] - [#48140]) (breaking-change) -- Add an option to hide selected Hyperion effects ([@dermotduffy] - [#45689]) ([hyperion docs]) -- Improve Docker and Kubernetes support for KNX ([@plomosits] - [#48065]) ([knx docs]) -- Add august doorbells to dhcp discovery ([@bdraco] - [#48244]) ([august docs]) -- Add dhcp discovery support to blink ([@bdraco] - [#48243]) ([blink docs]) -- Add Ambient Station PM25 indoor sensor ([@conflipper] - [#47970]) ([ambient_station docs]) -- Add broadlink dhcp discovery ([@bdraco] - [#48408]) ([broadlink docs]) -- Add dsmr monthly and yearly totals ([@robertdelpeut] - [#48253]) ([dsmr_reader docs]) -- Add support for Selectors in Script service fields ([@frenck] - [#48469]) ([script docs]) -- Allow specifying template entities based on triggers ([@balloob] - [#48169]) ([trigger docs]) (new-integration) -- Command template support for MQTT fan ([@jbouwh] - [#48413]) ([mqtt docs]) (breaking-change) -- Add image proxy to Kodi media browser ([@cgtobi] - [#47315]) ([kodi docs]) -- Add opentherm_gw option for setpoint override mode ([@Martidjen] - [#48465]) ([opentherm_gw docs]) -- Add zwave_js.set_value service ([@raman325] - [#48487]) ([zwave_js docs]) -- Add support for capturing renewals to dhcp discovery ([@bdraco] - [#48242]) ([dhcp docs]) -- KNX passive group addresses ([@farmio] - [#48009]) ([knx docs]) -- Add regex-based filters to logger component ([@jshufro] - [#48439]) ([logger docs]) -- Add color_mode support to MQTT JSON light ([@emontnemery] - [#47993]) ([light docs]) ([mqtt docs]) (breaking-change) -- Add Plex library count sensors ([@jjlawren] - [#48339]) ([plex docs]) -- KNX entities now have a unique_id, so can be used in the frontend ([@marvin-w] - [#48522]) ([knx docs]) -- Add operation sensor to Shelly Gas ([@chemelli74] - [#48462]) ([shelly docs]) -- Add Qingping Air Monitor Lite support support ([@arturdobo] - [#48181]) ([xiaomi_miio docs]) (new-integration) +- [@marvin-w] added support for unqiue IDs to KNX entities. So, as a KNX user + you can now tweak your entities in the frontend and group them into areas! +- HomeKit now support he CO/CO2 device classes, thanks to [@iMicknl]! +- [@robertdelpeut] added monthly and yearly totals to the DMSR sensor, thanks! +- Hyperion users can now hide certain effect from the UI using integration + options. Thanks, [@dermotduffy]! +- Got that one message in your logs that you don't care about? [@jshufro] + added support for filtering log messages using regular expression! +- The Plex integration now provides library counter sensors! These + are disabled by default by can be enabled if you like that. Thanks, [@jjlawren]. +- The Quickbar had an update from [@donkawechico]! So press that C & E letters + on you keyboard to see the beautiful new labels. -To format, candidates from the frontend: - -- Number format options in your user profile! (?) @? -- Enable turning off edit mode in panel views (#8625) @thomasloven -- Quick Bar: Use command category labels instead of icons (#7692) @donkawechico -- Fix rendering when selecting all in datatable (#8749) @bramkragten -- Add filtering by devices/areas to scripts (#8748) @bramkragten -- Add filtering by devices/areas to scenes (#8747) @bramkragten -- Add filtering to automaton overview (#8736) @bramkragten -- Show if config entry is not loaded (#8717) @bramkragten +[@joshmcrty]: https://github.com/joshmcrty +[@donkawechico]: https://github.com/donkawechico ## New Integrations @@ -294,6 +351,8 @@ The following integration got support for a new platform: The following integrations are now available via the Home Assistant UI: - [Xiaomi Miio][xiaomi_miio docs], fans, sensors and lights, done by [@starkillerOG] +- [Hive][hive docs], done by [@KJonline] +- [Verisure][verisure docs], done by [@frenck] ## If you need help... @@ -374,6 +433,11 @@ We are now explicitly only supporting secrets inside your Home Assistant Core and Lovelace configuration files (and anything included from there). Secrets are no longer supported in other loaded YAML files. +This change should not affect regular users of Home Assistant, however, we +have been made aware that some custom integrations may cause problems. If +you are a user of Dwains theme, the HomeKit Infused theme or lovelace_gen, +please make sure to update those or check with the upstream project. + ([@balloob] - [#47034]) {% enddetails %} @@ -1383,13 +1447,56 @@ The following integrations are no longer available as of this release: - Remove Hass.io terms in strings.json ([@LEJOUI] - [#48541]) ([adguard docs]) ([almond docs]) ([deconz docs]) ([mqtt docs]) - Create homekit locks according to spec ([@bdraco] - [#48453]) ([homekit docs]) - Update frontend to 20210331.0 ([@bramkragten] - [#48552]) ([frontend docs]) -- Improve Plex device handling ([@jjlawren] - [#48369]) ([plex docs]) +- Improve Plex device handling ([@jjlawren] - [#48369]) ([plex docs]) (breaking-change) - Add operation sensor to Shelly Gas ([@chemelli74] - [#48462]) ([shelly docs]) - Use Mapping[str, Any] instead of dict in Entity ([@KapJI] - [#48421]) -- Add Qingping Air Monitor Lite support support ([@arturdobo] - [#48181]) ([xiaomi_miio docs]) (new-integration) +- Add Qingping Air Monitor Lite support support ([@arturdobo] - [#48181]) ([xiaomi_miio docs]) - Use SOURCE_REAUTH constant for starting reauth flows ([@bdraco] - [#48553]) - Improve automation trace tests ([@emontnemery] - [#48542]) ([trace docs]) - Provide the improved service UX with deCONZ services ([@Kane610] - [#48382]) ([deconz docs]) +- Fix timer.finish to cancel callback ([@youknowjack0] - [#48549]) ([timer docs]) (beta fix) +- Remove analytics from default_config ([@ludeeus] - [#48566]) ([default_config docs]) (beta fix) +- Fix incorrect constant import in Ambient PWS ([@bachya] - [#48574]) ([ambient_station docs]) (beta fix) +- Don't care about DPI entries when looking for clients to be restored from UniFi ([@Kane610] - [#48579]) ([unifi docs]) (beta fix) +- Cleanup orphan devices in onewire integration ([@epenet] - [#48581]) ([onewire docs]) (beta fix) +- Return config entry details for 1-step config flows ([@emontnemery] - [#48585]) ([config docs]) (beta fix) +- Upgrade numpy to 1.20.2 ([@frenck] - [#48597]) ([iqvia docs]) ([opencv docs]) ([tensorflow docs]) ([trend docs]) (beta fix) +- Allow templatable service target to support scripts ([@frenck] - [#48600]) (beta fix) +- Fix websocket search for related ([@frenck] - [#48603]) ([search docs]) (beta fix) +- Clean up mobile app ([@balloob] - [#48607]) ([mobile_app docs]) (beta fix) +- Update frontend to 20210402.0 ([@bramkragten] - [#48609]) ([frontend docs]) (beta fix) +- Increase time out for http requests done in Axis integration ([@Kane610] - [#48610]) ([axis docs]) (beta fix) +- Include script script_execution in script and automation traces ([@emontnemery] - [#48576]) ([trace docs]) (beta fix) +- Include blueprint input in automation trace ([@emontnemery] - [#48575]) ([automation docs]) ([script docs]) ([trace docs]) (beta fix) +- Bump aioshelly to 0.6.2 ([@thecode] - [#48620]) ([shelly docs]) (beta fix) +- Fix trigger template entities without a unique ID ([@balloob] - [#48631]) ([template docs]) (beta fix) +- Support modern config for the trigger based template entity ([@balloob] - [#48635]) ([template docs]) (beta fix) +- Updated frontend to 20210402.1 ([@bramkragten] - [#48639]) ([frontend docs]) (beta fix) +- Bump aiodiscover to 1.3.3 for dhcp ([@bdraco] - [#48644]) ([dhcp docs]) (beta fix) +- Only listen for zeroconf when the esphome device cannot connect ([@bdraco] - [#48645]) ([esphome docs]) (beta fix) +- Fix AEMET town timestamp format ([@Noltari] - [#48647]) ([aemet docs]) (beta fix) +- Prevent config entry retry from blocking startup ([@bdraco] - [#48660]) (beta fix) +- Fix Raspi GPIO binary_sensor produces unreliable responses ([@mburget] - [#48170]) ([rpi_gpio docs]) (beta fix) +- Implement Ignore list for poll control configuration on Ikea devices ([@Adminiuga] - [#48667]) ([zha docs]) (beta fix) +- Bump zwave_js dependency to 0.23.1 ([@raman325] - [#48682]) ([zwave_js docs]) (beta fix) +- Fix verisure deadlock ([@balloob] - [#48691]) ([verisure docs]) (beta fix) +- Abort discovery for unsupported doorbird accessories ([@bdraco] - [#48710]) ([doorbird docs]) (beta fix) +- Improve warnings on undefined template errors ([@emontnemery] - [#48713]) (beta fix) +- Bump pychromecast to 9.1.2 ([@emontnemery] - [#48714]) ([cast docs]) (beta fix) +- Flag brightness support for MQTT RGB lights ([@emontnemery] - [#48718]) ([mqtt docs]) (beta fix) +- Fix infinite recursion in LazyState ([@blueshiftlabs] - [#48719]) ([history docs]) (beta fix) +- Allow reloading top-level template entities ([@balloob] - [#48733]) ([template docs]) (beta fix) +- Updated frontend to 20210406.0 ([@balloob] - [#48734]) ([frontend docs]) (beta fix) +- Do not activate Met.no without setting a Home coordinates ([@frenck] - [#48741]) ([met docs]) (beta fix) +- Generate a seperate UUID for the analytics integration ([@ludeeus] - [#48742]) ([analytics docs]) (beta fix) +- Rename hassio config entry title to Supervisor ([@frenck] - [#48748]) ([hassio docs]) (beta fix) +- Use microsecond precision for datetime values on MariaDB/MySQL ([@agners] - [#48749]) ([recorder docs]) (beta fix) +- Add custom integrations to analytics ([@ludeeus] - [#48753]) ([analytics docs]) (beta fix) (new-integration) +- Solve cast delaying startup when discovered devices are slow to setup ([@bdraco] - [#48755]) ([cast docs]) (beta fix) +- Met.no - only update data if coordinates changed ([@Danielhiversen] - [#48756]) ([met docs]) (beta fix) +- Remove login details before logging SQL errors ([@emontnemery] - [#48758]) ([sql docs]) (beta fix) +- Fix whitespace error in cast ([@emontnemery] - [#48763]) ([cast docs]) (beta fix) +- Update frontend to 20210407.0 ([@bramkragten] - [#48765]) ([frontend docs]) (beta fix) {% enddetails %} @@ -1828,6 +1935,7 @@ The following integrations are no longer available as of this release: [#48167]: https://github.com/home-assistant/core/pull/48167 [#48168]: https://github.com/home-assistant/core/pull/48168 [#48169]: https://github.com/home-assistant/core/pull/48169 +[#48170]: https://github.com/home-assistant/core/pull/48170 [#48175]: https://github.com/home-assistant/core/pull/48175 [#48176]: https://github.com/home-assistant/core/pull/48176 [#48178]: https://github.com/home-assistant/core/pull/48178 @@ -2016,8 +2124,50 @@ The following integrations are no longer available as of this release: [#48541]: https://github.com/home-assistant/core/pull/48541 [#48542]: https://github.com/home-assistant/core/pull/48542 [#48546]: https://github.com/home-assistant/core/pull/48546 +[#48549]: https://github.com/home-assistant/core/pull/48549 [#48552]: https://github.com/home-assistant/core/pull/48552 [#48553]: https://github.com/home-assistant/core/pull/48553 +[#48566]: https://github.com/home-assistant/core/pull/48566 +[#48574]: https://github.com/home-assistant/core/pull/48574 +[#48575]: https://github.com/home-assistant/core/pull/48575 +[#48576]: https://github.com/home-assistant/core/pull/48576 +[#48579]: https://github.com/home-assistant/core/pull/48579 +[#48581]: https://github.com/home-assistant/core/pull/48581 +[#48585]: https://github.com/home-assistant/core/pull/48585 +[#48597]: https://github.com/home-assistant/core/pull/48597 +[#48600]: https://github.com/home-assistant/core/pull/48600 +[#48603]: https://github.com/home-assistant/core/pull/48603 +[#48607]: https://github.com/home-assistant/core/pull/48607 +[#48609]: https://github.com/home-assistant/core/pull/48609 +[#48610]: https://github.com/home-assistant/core/pull/48610 +[#48620]: https://github.com/home-assistant/core/pull/48620 +[#48631]: https://github.com/home-assistant/core/pull/48631 +[#48635]: https://github.com/home-assistant/core/pull/48635 +[#48639]: https://github.com/home-assistant/core/pull/48639 +[#48644]: https://github.com/home-assistant/core/pull/48644 +[#48645]: https://github.com/home-assistant/core/pull/48645 +[#48647]: https://github.com/home-assistant/core/pull/48647 +[#48660]: https://github.com/home-assistant/core/pull/48660 +[#48667]: https://github.com/home-assistant/core/pull/48667 +[#48682]: https://github.com/home-assistant/core/pull/48682 +[#48691]: https://github.com/home-assistant/core/pull/48691 +[#48710]: https://github.com/home-assistant/core/pull/48710 +[#48713]: https://github.com/home-assistant/core/pull/48713 +[#48714]: https://github.com/home-assistant/core/pull/48714 +[#48718]: https://github.com/home-assistant/core/pull/48718 +[#48719]: https://github.com/home-assistant/core/pull/48719 +[#48733]: https://github.com/home-assistant/core/pull/48733 +[#48734]: https://github.com/home-assistant/core/pull/48734 +[#48741]: https://github.com/home-assistant/core/pull/48741 +[#48742]: https://github.com/home-assistant/core/pull/48742 +[#48748]: https://github.com/home-assistant/core/pull/48748 +[#48749]: https://github.com/home-assistant/core/pull/48749 +[#48753]: https://github.com/home-assistant/core/pull/48753 +[#48755]: https://github.com/home-assistant/core/pull/48755 +[#48756]: https://github.com/home-assistant/core/pull/48756 +[#48758]: https://github.com/home-assistant/core/pull/48758 +[#48763]: https://github.com/home-assistant/core/pull/48763 +[#48765]: https://github.com/home-assistant/core/pull/48765 [@Adminiuga]: https://github.com/Adminiuga [@Antoni-Czaplicki]: https://github.com/Antoni-Czaplicki [@B-Hartley]: https://github.com/B-Hartley @@ -2052,6 +2202,7 @@ The following integrations are no longer available as of this release: [@TheNetAdmin]: https://github.com/TheNetAdmin [@abmantis]: https://github.com/abmantis [@adamjernst]: https://github.com/adamjernst +[@agners]: https://github.com/agners [@alandtse]: https://github.com/alandtse [@alengwenus]: https://github.com/alengwenus [@allenporter]: https://github.com/allenporter @@ -2060,6 +2211,7 @@ The following integrations are no longer available as of this release: [@andreasbrett]: https://github.com/andreasbrett [@arturdobo]: https://github.com/arturdobo [@austinmroczek]: https://github.com/austinmroczek +[@bachya]: https://github.com/bachya [@balloob]: https://github.com/balloob [@bdr99]: https://github.com/bdr99 [@bdraco]: https://github.com/bdraco @@ -2068,6 +2220,7 @@ The following integrations are no longer available as of this release: [@bieniu]: https://github.com/bieniu [@billsq]: https://github.com/billsq [@blejdfist]: https://github.com/blejdfist +[@blueshiftlabs]: https://github.com/blueshiftlabs [@bramkragten]: https://github.com/bramkragten [@c99koder]: https://github.com/c99koder [@cdce8p]: https://github.com/cdce8p @@ -2099,6 +2252,7 @@ The following integrations are no longer available as of this release: [@elyobelyob]: https://github.com/elyobelyob [@emlove]: https://github.com/emlove [@emontnemery]: https://github.com/emontnemery +[@epenet]: https://github.com/epenet [@esev]: https://github.com/esev [@fabaff]: https://github.com/fabaff [@farmio]: https://github.com/farmio @@ -2131,6 +2285,7 @@ The following integrations are no longer available as of this release: [@kristianheljas]: https://github.com/kristianheljas [@ludeeus]: https://github.com/ludeeus [@marvin-w]: https://github.com/marvin-w +[@mburget]: https://github.com/mburget [@mdonoughe]: https://github.com/mdonoughe [@mdz]: https://github.com/mdz [@mib1185]: https://github.com/mib1185 @@ -2175,6 +2330,7 @@ The following integrations are no longer available as of this release: [@vlebourl]: https://github.com/vlebourl [@w1ll1am23]: https://github.com/w1ll1am23 [@xonestonex]: https://github.com/xonestonex +[@youknowjack0]: https://github.com/youknowjack0 [@zxdavb]: https://github.com/zxdavb [accuweather docs]: /integrations/accuweather/ [acmeda docs]: /integrations/acmeda/ @@ -2200,6 +2356,7 @@ The following integrations are no longer available as of this release: [august docs]: /integrations/august/ [automation docs]: /integrations/automation/ [awair docs]: /integrations/awair/ +[axis docs]: /integrations/axis/ [blink docs]: /integrations/blink/ [bmp280 docs]: /integrations/bmp280/ [bond docs]: /integrations/bond/ @@ -2223,6 +2380,7 @@ The following integrations are no longer available as of this release: [dhcp docs]: /integrations/dhcp/ [discovery docs]: /integrations/discovery/ [dlna_dmr docs]: /integrations/dlna_dmr/ +[doorbird docs]: /integrations/doorbird/ [dsmr_reader docs]: /integrations/dsmr_reader/ [ecobee docs]: /integrations/ecobee/ [econet docs]: /integrations/econet/ @@ -2266,6 +2424,7 @@ The following integrations are no longer available as of this release: [icloud docs]: /integrations/icloud/ [incomfort docs]: /integrations/incomfort/ [intesishome docs]: /integrations/intesishome/ +[iqvia docs]: /integrations/iqvia/ [izone docs]: /integrations/izone/ [keenetic_ndms2 docs]: /integrations/keenetic_ndms2/ [kmtronic docs]: /integrations/kmtronic/ @@ -2292,6 +2451,7 @@ The following integrations are no longer available as of this release: [mcp23017 docs]: /integrations/mcp23017/ [media_extractor docs]: /integrations/media_extractor/ [media_player docs]: /integrations/media_player/ +[met docs]: /integrations/met/ [meteo_france docs]: /integrations/meteo_france/ [minecraft_server docs]: /integrations/minecraft_server/ [mobile_app docs]: /integrations/mobile_app/ @@ -2311,7 +2471,9 @@ The following integrations are no longer available as of this release: [octoprint docs]: /integrations/octoprint/ [omnilogic docs]: /integrations/omnilogic/ [onboarding docs]: /integrations/onboarding/ +[onewire docs]: /integrations/onewire/ [onvif docs]: /integrations/onvif/ +[opencv docs]: /integrations/opencv/ [opentherm_gw docs]: /integrations/opentherm_gw/ [openweathermap docs]: /integrations/openweathermap/ [panasonic_viera docs]: /integrations/panasonic_viera/ @@ -2345,6 +2507,7 @@ The following integrations are no longer available as of this release: [solax docs]: /integrations/solax/ [somfy_mylink docs]: /integrations/somfy_mylink/ [spotify docs]: /integrations/spotify/ +[sql docs]: /integrations/sql/ [squeezebox docs]: /integrations/squeezebox/ [ssdp docs]: /integrations/ssdp/ [stream docs]: /integrations/stream/ @@ -2354,15 +2517,18 @@ The following integrations are no longer available as of this release: [tasmota docs]: /integrations/tasmota/ [tellduslive docs]: /integrations/tellduslive/ [template docs]: /integrations/template/ +[tensorflow docs]: /integrations/tensorflow/ [tesla docs]: /integrations/tesla/ [thethingsnetwork docs]: /integrations/thethingsnetwork/ [tibber docs]: /integrations/tibber/ +[timer docs]: /integrations/timer/ [tod docs]: /integrations/tod/ [todoist docs]: /integrations/todoist/ [toon docs]: /integrations/toon/ [tplink docs]: /integrations/tplink/ [trace docs]: /integrations/trace/ [tradfri docs]: /integrations/tradfri/ +[trend docs]: /integrations/trend/ [trigger docs]: /integrations/trigger/ [twentemilieu docs]: /integrations/twentemilieu/ [twitter docs]: /integrations/twitter/ diff --git a/source/images/blog/2021-04/analytics.png b/source/images/blog/2021-04/analytics.png new file mode 100644 index 0000000000000000000000000000000000000000..f5aea8243fc759a6f4974b8c30096b1c3618b882 GIT binary patch literal 80424 zcmeFY1y@|ly0DA8yF&=>5)xbk!D+m4*T&rm?h@Q3xVuB+5IiBcJHg!p+|J(noVC8S z@BIOHj1OjyuAb$ys%E|NR0Kfr6FLeB3KSF+x{UNk6(}g!94IIlG$aJbooo$fQYa{t zc`FGCfQ*C$6~M{f+{(rb3Q9U6ITcYYaS`Y9*=xxMSs3hi9538LTv1sh*3W@1Sjq8l zII`i$&;zk7)rOLia5MONaLTonpBJ!D2?z#5eS=t-4w(pSN{=xG`%b}EYXbI@>ErHn z&ij)q&S!jAu%Z{+vNXiCBv9#FHdY_=*x#}V2Lv1;GUOqii=qRaJh_mW1qJb_xQt%e zDD7Y^XVz+oCvMJOUp4bD;khWF0MvaWKE&*}o9{p7p3_X*KmnS<*LgqaaE)dofuz5{ zU~5D>9rAWl?(T3(Z4VoNrCvZfg85AE+%~NS^^G7r_e;N=S*6kK@ zn@_L~R!&NKI?rhLTbqCZIjFpNY;(F-T8qQ=OM2!j=e9CgiZhV>xgT{pO;E@At6;_} zYdY~|gwQw^EozY%cDTCO{%dHRYs?G1sXcKXR zI6bc9-PeCJVCNY83gE22>c=*()DJ7rl#**`FhMN1GP=N~z4wRz@D-jps}iwX*8pgL|g@ zx#+Zs*+*{GPiaSxG>1^RV3Pf`6bqef-#hWq&xbNkam0|43HN?R&-(lp2|<1XA)YjY z_1hSQZD2O776X0}N&_*=P7yK@8RwK6Nq_HTFU98{?gD=JYpcZGaaiOc2V-AhH<}3o z<`cm*CQul=FnKS=(-!(6g1I$Njgpr;(^-y`Ue}1Q;iCAKP_}uP(E;$a&=@`N9#E7U zaWljSUquDe5IsbZxB~EY0tXG@8DMA)VHaSSdK7C(X98h2I4lw9dx#yNb)n~bSRE)C zL`6KH5qc3h(8RDXzKXt+Cgu7p{|598+E`paUIY(CQuG3VlY|oShOd!G8#!6D2ms%R zS{{TUHk`-(owk&;9rZ>W_Pfq6)abyGT7*i(%-)|ybmM^%8w?(7St#tEuQtU!$aOI^ z`=2)H?$LbU!SKu*gy&c&dD0C0qgZA^#$OjoIn-d7;AtgUCGiVJ0kfqDYRu)ZuCPU- zT_1g=On$t32WuO2D~gz3@I&w#=33>N#09>cU^Q4c3>venrDc-zjwe$ zg|jVhX^;u&Y#Xp&gU#B) z6a%w#*&^A*QP*V6ayWHW^^`-wS)W<1*|+7I>IUW5GvhN0*1Ana*2&hxGhQ>HGggPU zhen6#hoG6eG6NNVsX^t5(ib)1rugyQ5%^#K{W}qY@->vY#Pqu+)||w^~IsnQ9m7 z*tK+;!|U+rAXhO}RcrUpvCUB*oy@KNvwE&+<#Yg z;W=7wT2y!2p#QM+AnP0V=x5r|kXpO^8{ikY;xfar`trNr|>~+@-L0w9=<$Li+p^Ls)}o;w8dtPvx`%X zk%=ygdLTL?)FG(|&!lLfIhE~H>|_AbLZ@OS0unji4f{`~@I6ONMo31q>}O0(WO`fW zOm;?l((hMH?oWy&1j|G!ETvv2lMYqwVbD4!R3spJ+N^1;p@K2}x&1{q7#Z*d6)xl% z6+BZ8)7u$cMSrof;DYh$B=Ns~uoANp_$gc*R&=I7ITAi$IX+-PXGVdmI(V?&U)4_j^o!t)prii2 zctuDBq3{Iew^vVWFKm0|C*%G>W`a95Bi6+xJnf9mM&I;{`aZMgG1%1kYN~2!g9}iA zo|skdQ*s@%4(bg`D&g%j*1d%97uhe3r54G<<=G-%{qdd`nwA`InrGLe9tKn8j%7z> z!PT2pZJl#|whv2RTp5qr=Q=9a>!3TtIyY~n&SIL14vQX&d^64Mte3_YbUPoOQyz5K zlKGNPR%BP0*2@_%S?w3i>uvj+Yw-Ibb&|o!G3xE=6&1pE`}W=7ev422ie1^X0^Pr9 z9uFp~d-N1$&1cOz>N=d=L>6%yO13Tbrd)aWd1!goZzJ!RtlwHs&9=?Wp8Q;G0aH|` z&SM@ct@xjOUJpn?$PCqsxgJUg+Q|F8aU~%WW=Dy^x8fJem<8vhe?pfiU0K)kXd-Ln?A$sdvdjW zmK!7BeYJAzthX;QY0!z~uxW!>v3)H$6-Ce1X29>3?%DPbIhI_kxIbCY&Hw7vI960~ zP<}L<0E>b5#iRFr_7b4{Bn)03KJvckIKHcS4pCxI8qFaQtn%JF zKOPY6>1o<`&bjN3?6{ppMFt$N`GkEmOD-@>2EV|G#KmF@&i3nTt4?o?|lmoX5NjBfnoT#nS=+m zb}G5I&;_U<&u?OH%VuP1Z*0cqVe9ZG3zVP-KO|^t z=3+$UVQXXO%--3wBOEK0bC1E_N<1R!9m~XHPp9BM(+P z=ePeZsY042%)|9g@L$#Z zSIl1x{dZ1vXEP@Wds|3G7vaB#=I z=;LfeA2rFlJ0&DqmqNk=NiXF>cW7p6J;~Yt>cBX7)W-$D50P+qAGIFM$kOoea4Ko# z9+a@OT-FDwAH+Fi70cuuA5}{~cPL^A|1MOB?>jWQm5_3$RFh~LlKE>T; z#m2^_ygr}#t2A0FPw}17(4XIL$Bj*93kVTrytidi61)iB=go4XQ^=sP@4N`5m$_SU zjzc5opK%_~Zo~#Q+oVU6@l79XDi=t}JY4Q}O@{pJJzeeC9Z%=Zp%KG&QGL0}ef_pI z80DIDf7oUZa4$&-(PHBo^`)^ z>52CzMV1ia)W8Bkd*kWbt{7;P9vjdjxgy>34-UMwB{yU2-Dv4sZ6?DQiyiJY^qKIe z1W6e@Ag|bdBShB~>)o*w*35U-Gtytbew|M4WC!0Co_1WB1-~#S^t`PrW^rkj5)+vb1c};$BPZVd(ORq z@Y78o&D?peOVci|n@+q!e%Hfb7Cvr^$r%l1T*G80^#sPi1i6sBL4b@GA)s-8R;MF^~(VHfvKOQVn}!@ z;~aATHsh#ZksX}!(Sq&cNK(id2*CsEo(6aAo*1&4Q#nFK(qE{j%T(zf&ir4G%&)PD z=Q};GeD*-EFVC05l>YafDYHs_eZL=%YUDcHPF(bYzk2OwyPLbRjEnr$*I;yLZNdIx zhL1|$op-)r=Q8%e2|Ea(w{ZFu$)%=f>U&DQ`p{+3t14_%)POIa#y_n46wo_ddP@+1 z9d2ed#}Fxf;zN)*j{aI#SYWt5sS81ejn8??U2Z4Zi!JuK6jQ(^YxUl<;!L}Qw6ru+ zJpY#mi-)Tz5uyE>wmp*GkAmy|uU)?(HwtGn4+b~pVH%%LDnge4wE`C5FtA;D} zJ$I8;y1ZO%-_*sDUcvcT(X+8BZd^tZ>$;yT(Oz6!c#XfAUI6<(xy0#7zQ7`{I8gfC zZ;G}cRTe|m-i&TusrVOG)#B(RRvit<+$r{dfsr0-xZ0n(BiRPl8B4a^%;_Xb)>+Ro zX*F7Y(a7Pn!zGw@+8ssKb%v}AsgW;l!}f`R?v7J6-7klHVc8RzAI3V)z!g(XcB|Tl z^EGE}Iq~sS%o>&PH%IeF{Ee1*O`*u=#VD454|R zw(ZjxfPF^ndOdVFxTZTjorQjKu#|p7_47C_uc)3jQ>)VEaR$}1(xHg+_u!gD_YziD zCNpcMu<5lIjwTb~0*qKHzX*C>N<*f}M7{-T5w=~E)Hz$<$%5CU?$h;8C3w3@KIgre z(_!A%AD<{a73_lDDY#jecQ<;29-oIjTz%|0P`O7@)}eqWzP=zVDeW~(?-fBhXdEQ+ zfP)SknmFsh6*Z=gtZ>2ymrtGVm~dFpYtG&F9xni2kNLcnPnrDNMsPD3>Ni9KSp>Y4 zN$?^Q+y)!Q@cGoAsBQzt7pmAEzfkiP6l%7OZ65P_i|rjNB;}YnOaIVa!&F$xq1wHY zlF2k43Hy|G-ONtRI(z9^GB1FKZQ%IZ^>^TJzXgB(BZ9~jI?4KxR@RH@PRqs_W*5HL z;HdI~r*H6DE>z0pdr=8Ta^`okPfLk}rWd^*4|M6YM|Z%#$)K_t-|<1rt*m`Z z$&LY^HTjZmmDFF%^!J>HRX%WrHO+->;nAe3gRc5|PR789`q*EowDVL6FL=Gx;r&7B zVU{|~MeQ0P+tZv+#vMb^9b{k*VX;L|E7ByIb7aczz;;Kq3u@Qc{9<*^*>ioLn$f{cuu$8Dl>$ z{zD(EF`L!#QL#5RR=4%`;VK9))n*G_QYjgM`Oifdhjf z^7}k!ozo9ASNWwR$7@vX;T#1(-oq5EWm#qR*?antB`NRVXNmXMUMD8NyJ*o(kK09y zrfI9m#g=b`qd24FaJxZTdaxsqy@jP^-LC@-FUw^9EJ^%;TZsC=re2=3pHik;G8)AW z{>2xH6U}uG**JyvD+L@@-`y2VlF%-A#ko?V+z6a?ng}It2`6cc|F(e}UCWmU>pWy$ zgE!drrS!d4P8V>m_Eht_IV{3AVVDNPHS8@3AfNmBygcl~fM4KT$U+tASxuTmDI&St6D>B|X0AB&qwfLi^Bb4xYcAWx$f;P1SDpv$eG$k% zDTzEc5-J_Jx_n0?eb2JkLRWPb#$$5|5krDgM7uoeRDg_8BF#}>V#*z7q{vNpYP#)5 z3zDUAm-WWBcJ`kMO}+P59`TY&EHtuGQOj=<+392zhxL=P_`aIDE$cdI@PO@J`6dOK z>dGU6rAVtKWSJ!|_m9}zgGH__vV0m?l@Vq~-%QQ5t^`DSGy6CzW-u1*HPF3}QPbl- zAa`?BT!k8Vei_gtJF|&S{c)sjoJ><1T?!V;GeyUDVo{lb(BL|H9gGqX?Ga$&ucp@XwN{PKpav_p?TK^1{8K~s^Gb7wF)t7VtdI~_pJIx$7hS|>NY zn)*2xvC3oBGc;iOUH+$COV1K9wzl6I8wVS^^|GYDx!-i*n!vy^W{0E2XjLL2$(d92 zy86q~=SY}z>9pASk!Ay!47^X8OqF{sL#3KUif}OvoArTj^KD8bzf(1%;-OW1hOP7h z!x5AV`#!>{@n4XU9HhM=jI920EePs6ZwisT??t3UD|Ol8+o>?<_S1g2!B@<4uJu}V z8e^r{?O*Q#fNSN^`T2h%vv|KGDGFXKTIAAZ>dhJet@z>^#fY0_<0ym@v=m_5wzP8x z$6Fz3R_>7U^kI9E1PP8|?BOf!z3l6BRT<#PsecL9vppDN zQs$uD&jDG76}u>JTRr7rXyW}~06hpbot3;x5`sn5A|02VNt!X=CiE`94e291tqgMGaO#?gzoVeGf|ey) zk+akh&91|E6Q9ujOHK9kH(%+JqB@+4Oa2z$Xq(d{oo3gGw-d?uXUfU$@5-y{#Tb=w zn;)hKD~kc`XO$Uxj5nT*#v;w>vi)_amqU*|1au%lyHkg+#mobH=KdweM++F!S%uW2AZ30>zvCh<#FEuiyoH$=%3x?@vut@3&Vw`6 z*Q|M2`cb$WpAM#@Fg3&h16k~6fGeA*%GMV=mHStPgRW066Hh8~u32~*vITrYb3pDd zKWWL?=AoT2lN3uUeEpR!N41?KqAQixV-yZar`uf`J6q`VWA)t@rhDXhNt48p2d{G_ z2u<(#&+d%-ip~)E;qvZDWE8w6xX+J2PkS~Tx-8|7l32ZdRfr~2Nm=ReS9($K@we^F z+wRTnYLmA-Ma7k&DuHbfSI*z(elyI^-{Ap`27qT2f~HX` zOj9YMh{9s)(9I14kA9T81fN1+08>G-!mY}zQSl}xM8Kp-Ho0>}#*u=%>k$X&cYhaHDNP>$SRl6Vq&f_U8!_o9=mo2gP(Q$@R#(Drv+OjT4v(u4*m4fRnp>{?Mc9 zE@xPM_}U#E_-stDu20n+Tmz;Z@arJbR!fI>kVNKtTc5qFbc-C$IE0lxc#1VRjexKo#v=DJ<*WvSldeH=WLT}oVes1bCLMIJO!rB4+}WGf{B3{b&e__!OJ&?fEnNt_r_ z7rBL@==}YzlZ~#ubD74*D=5qK`SGJxU=>Wt)T^t$Ve$p-QL-FcVUW`VH^EoMq6WE+ z`X4yCB=KMv_g^cqKM9MHoZhnFC(is1so05fb&^(}-KN27tVftx;*8LK2Q9G20{lwUHmoJUWuZ_Vt6XWlX#8e~cBV(Bx#M7%OwW%`J z-%rUpzS^`06LQ->0fuXSPqy9NNi0bksp5%nt?e0gnrX{E(1ip+E#~zU9o2?jMN2 zZJI^izBsPVFhpTy97UXC>=0l~LeCn;l>KC5W5b2&aCf@ebaV#MseQGd03TqGlUxg7 zO~Sfg9*;~>5*>Mlfq=sP^1L*M&Cn>&Ev@LdtG`aiG-43}+mCM*dSWOV0SIzC#3F@b zYz~e*TVq|sR(%49a$sLwy2HoK{;-K{zZT#NJUOF=SV`~!hv>eC-hhZhwRfnPridn8zg$N_U{}M(*d*U;!S(2TY$x2y(L=C2?m$DTuWR`hC1A|+yLWHT~tUlsGBC*S!8FX8)PAY_(O?{0pz>8(3?qWpFk) zTY34Z+%#3FTukV`hF8dq;J~s*S1FYtb!$o16G?-PL5{u9ponZ*HYViR6co6Q;3I1k zTCbSVddq~$!Vg?3@6>`nO{wkiouwX;rC_3%-~4W*CZGr{6LW9 zd4^OcGDc)E@o>Zt(+Yb&l%Z|`wgH>x9tlBm7-<>yJN-?55J@X^8 zurSUbspC;7mJi`?b((FwaB!j}BnnoRcqI#Xc(&vsdV+c5kE%Nqy~0EKBt;sJeRa34J(WRO zJPy0ro4lt0R>NJDQXZMNPOv@<>L`!&A4cqMKbk4 zv`rU$W8eAGt9~l88)%tLHE=6kFVU*eH|S*9MdnqhsHx;?Kdttp;)M%?hedJ8shDo?9RDKLrA&~vOVg9tBzF2gWyyhv#7~@a{*3k0e zjJ?T0Sv0#i<<1P3yU`#AwJa<;ZCWo3M&hc4}&7x7tXtl+dl#E8@LZc2&e1NoN2h3mmz3B&=0| z%d3fqEBMR5yPTEM-39Vo!td&F=+BO5f=a5%ZTk8>ev+yUN9xIw11plo%~OX0w;_i-qVc1xeDh=*uWPdUw^@zjnA5g*7}561uvQw( z#!^i4?@3S*uWuX6Rvz>DyPu(y^@)&8&6Ud%v6m>IrSf*|_Q$xgz@P&t2R)BF;BpW{{ z&qG_l)&zURKJZ}(n_c@}r$#ye3K2BipiN}0FYo=ds)mYQgx1x|eRYsZL zi9zOawGfX?gg-zGyvIG{buzHNFnTY~9aSNNU@kae_4{gErpZ@>ap$KS%_y#H*}!;~ zTW@7L$WEnlwz64u#y6L7my|8X8P6a(3iX3nNe^N<_twZEp<01}van{i*yyT*UC2k` z_3s_%2ka*fWuc%OU-X1`t+%q!Arm_17o8CN6)TX-XeQBdDc7*%*tS6Iq% zi^84qn0N+$VoOi%UpWF*(y?H=^{P<01zcJ+B`wzI#04o^AIk>UnQNtf<}m6*$L$sk zyoP74{k23o2q363&J{$w=qD!{`$E(UR2(O=aYYUN3dI~-x05Fpha7*5;^&pabMds4 zVPVs+RXIVDY+F)7gFM?|oecZ}iC(tfVL z{=AMehE9i0^^LanZ9ebvpzt2v{7J)MhQ(h(WlqmGueO~hq5T~{o-!$0vso^f`KA7H zS`B5^hyaS`Vo9eFt6c`?n@;CT10Gy6j!60pH;1a=nWx*zwG0s=3wSwkufYgj61^=B z&6qo{(n~Ws>7(~eo#M7lmC<_j6{@N;JMTWQMkkAn3e7SRJ(cY-PRmvI7>831g*4?- zGWTmRGndteh9(+5Bixaa`hAj3a^#NouYEnFG%Dxg$h}6t-kD-s$!#5h78GWfk3Xy4Tz`} zU-W!C3N3u?R^c+P1G?vd%H*S&wcLh_7^XU6dMZq+@vx&EPJYTdJPKisjh zmm&M5@7u4dUmt7T&8b9+f7cB@nbl|#oq-ZEH(}_94_5 zyrEuCl4+S!*}yd3U8!R}Ftq=-ow|lbbb22S<^ewamSyQ2Z^-!KcD8WzGk@On%D1gh z3k82)9=56)r(C^CJm!XXaMdEkcsHQ^fzf<9x%v$Vga66((`wJ zHs6f_*OX@ z07HaXa^R5?3&drNu+DdwjRcSB-AU|weAb02**^Z5+;FS=k^_f($|@^1$g*T#I!VNR z`ulB>gE32c6NV9Gb&E;zyr_2JL6JStoNd!+SSD`MZc~Ptt>V#5@95WvYXyMGTGh0h zQC8z~@A64&qNk>fBQRIaN+kK2ixHmix9bs!-yUP@z#^f2i}v}rFSs&qPn)4-&M}@& zw{_j9c|sH?IvIbeVAHnpOF-Y1>%=^fi2TPOM;8Y^y?WCKeZQeYKTuyUoJbnq++lSl zM2lzzH#_KssH2X)87ejwteCx76b!oX18Po#gQMF{L8z&q4iyYJg1OjWNixqqI8}{Z z;f4AO{9M(273~TxKxZwP&KT$SE=Ii|9Ltuu{>SjT+$PZcT%xw?;S6Ju;cxvK-L`s- z;;L-8+mV0`lCz`bjSt_c*z$tL*}$E|$9KTEY%h^Y$3MO;sz$hKO}o64S+ok&Wag?b zljYd=m+SkxoIGsU+Z!b15uqGq7^l6Dp}mzt5oYi5YCB7ZM2s|mZ_~b+%{4p2RP29~ zOFTN}cUA^#reIX4P2`%!^tJh`!A|;hdH%5MQu|cv2<*pb#GL1imhsio`al81rf;d> z%oLc^PfAUG(&gOsLrdlNzjQju;!=%K)BKZ%P!JD$gLkr7x)~iFq>hvRSJfJh8T?`B{t^QU1E^$2gW!!@>fBx_IEhK!AEH=swi5I-!|uua(M0ort)5|t0zPOY;|7NgeqWs$Y@fPX5@d{H65maBZYoDWJE4Gl$(k*f#&FsHZ36@TjwU zU@RwT1gy1_xaG9B#Ax0vwYj z$4utsA+*G!`w&0l;jVeK%T^ZqSPSxe`=EznhatM`(ZaXi4_C|f$Q33t=`)joHWN^l zIr%Drn6?ohghOC47hn`5fC+7{Lraar0 z)>|A0+&UoOLQ77V>vrX6KU|T|#2Q6O4G#e2Y9Ta$9xWj7xz0N4>xE5gKl%Aj$l%vz z+}x()%dnLID_@{_*p7cd$yN&a+EK6rOq4dcen(_1nDrqv4TM|6f6z!|MOU_Jjtk&^ zc&Af%WumT8%I;Q#JO9WOvPEt-8#uUpSP$Bbd!m}-_^CsmD1MEByPr2>SiG6fyj`>p zrYVBaXpWm{k2a^SnmOmVFuk4|oixyfyy2d~zn}upy3|sursQqD$SJ@S(g~@LE_fCN z#Hecw|Ni_&-!Cd#+7Ko3>_>k+k=5sty1sp_y}6+K(fgbGL`J`P2VC@ijaD3zHS%vdbp zmU+vmd;!yNMTp#a2m+juzPgl`X7*@0SJv*s!L*o>{F5U08$okAH^K6?XeL9-(fPsn zGu98>iKmcBSc7DXSi85RM^|@^W)3}MQwG2=s%wnJ9^y_@UKlU5c8?kY3NbWFVe`8k zr?G1As5cFgkP{N_H_?IWGs*b_1n=wXA0jcxnQuA4zmCs8s2)S`h_2IN9ERHqFn9}j zFH60*?>X)FNbQiLwFPL1+pX88DF9CiR1)Ahms)Y0Bji24o7W8ZT9pmFuNF1>z}8aR z7fZr3%3QfOk%_t`bJVemPlO4Xu;Pk_MH!X-NFBU9oT0SP z-#Pj}3J_iGD;*mdO97tvjv9aogW*E@&TBTXA-KOXcrb!Pr1EN>@}(d6UtMm<0x9Wo zdY6iB`9e6{#^&!?-{qWaHmS=lTl2JG(a{HrM}=DRqNdvnK;#8;KNP$ueYF&xW4b8H`3)e;Y}=Z^@^}2a?%}GKuS|_;+7|LI z4#-kFl`EjbELYgK5kyJS>G0gpv1IH-_5ohbZ(&%~xC#I~&Z7~35DS_EvO~mpy8v;k zT%q|K^LLgfAi};S6L+CT;V@VBsu+vb193-*f+e8na1 z#UoC0^5!YyNFD@V z#nBsGCBhNrk|ty!+*K#}&joV}l#o1^2OmK?v_6>VfmQ4_o>GZAvYS zP5t)fWg6Eh+B$wKHJyfRY^{u+SUyaY_Y!IU5pVR4e&%6dM>#)BjX%kAf@2Uj{;cax z|HRy~={|20Wcyni6_(&#!(_=#XW|oJe52VqI|lcncMw~oLsU73&$*bw!m`_3=(fqN z#P_|<(euLaJ%0yvh+`rEn4hGby4-{FZqCf|*eKmhI*+R4M$0?x)v7)C(iea? z1vz6xt0RkeGocAqc+7KIUX|*;-$G?C8ePd;Vx=pt@Af8oODbJC76;cp<%JGPcvKNQ z(TCe39uG%VLIN#~7pk=)PAv|HW?D=TjNOaYHN~=HTvr7oSo7om(TtW_Y5x~J3#b(B z>GqF6ZTn<`eI)obASc1Fs~h6PWh`1IYr_D^bo)IAqCAzA@ZltN5TMvnG{ zdK`9W_f@Og>+_vSB3rMAdMjoLO&SvF8qr_gga2@Oq8e23OoKn8yWSZd5ASs@KDOJD zbB8{at5+1WhShSU!7oo-Er>IQ%)*0Ei{IHzYWmF8)}Dbp37&**O$4uY5|ylJF*R^I zdW7)i7Lal2ejzx?f@u3DFy}-ndaTnEW)T{WmxezZM^oZ4I)u17j;C=>m#Z_|;x~lG zJwrIOU+*x8xdx6@ymD?(q{$Z^jOEuWwHn~&bPaZ+E~3*$2<++{rkYTuLma!oDdC(K zR6ebyPbz@TKx9y!Ui2j{|-_T=$8*-sfy7w20j-JbGmFHgW zTS1*w;Fqre$er&IFq>f43K{yxy$}sr$*8ed^y}Mr; zP6H;fn`eelf9CY+Mal`P$DoCh4PvK-moqgyX28Q}?ODQ)Gu)Dy5=yHgv>G756)@`j zsvaPtv|uL^<*NUMFnaUjb6so~x}>%tdJEeP>{t_f$P$I7k56ay{4X150|%*W>8P~J zz`oc!-UWv&ACc( zj4WQXn0{lKknN{M6fp$WM52eGSIml!6MmGQiUqk(4SJ=k@%NWCrV;#wav}*qkj#9G zQ7i}~Y6Dkmciif@ZDS!Bw}|GZQfZ2L1^0iH{wBVBB!o+$It_qB6(BDLWg;+FCFFG8C22H^Fm zWdUPeT8+K1EEETFCeeOH%U6TyOtg<)1KC4g@L< zwP@o||F0NMNX-Au^M9Yg|F7qP>8P4sr-$9$e#^LKF%4m*^=rH_DFjQmBcr0O_;axl>0%7iDE#IcDfyf} z?w>*Q#JQiu?fwwLH@g^@Ua>U=qn}_GT?Uh|lbPWy%3tpQQ+Npd-5}1`5kCxJb`3H< z*t4B1H6^~cUHX>9s47@jt<@lv+usC%w?-hK=Mlurx}R#`_vMc(V4c$c_vR5n?mi9< z4rIp@{_&8kIsb+c^WZDq!#lp}ZvY2jg- zf#)th9|X(o5r5~fA-dS@-z^Byic~5zSOXH;9k->r8MB0a+xM3U4SY5im8=j)`yr}0 z(;weli$=As)`#nw_QUcdikQ+Pt6f4QaR_qFGsaxqO8wo|>G!?k!FqSM%{o|U!?#x# z%?uc@<;+eVrh1vfTb;c9F-$7MI&G&=)mlB=bYfOquE@=5EOS#3_+i z-Iw22N^Sc&-i2-_OOId(nyA+y3%=iqS`s3fdcB!9P$^eqgb;*r5M00KWBMU0QO_ev zlx-{-U!m=C^K_TD`v?R(@4@MC*c5Mj*vs6_v<>D)Z7I}sr0F9pE)WQKwa;Od13Wk+Hqiirl524}b*G^6B207?ReS)bRjfYGx ze|nN&X6G}gv>z-&@F_XZ=A)A{&GspZT>A1pV>t)9CsIrfW7NF0gnM7TCP!5 zuJw7g>u!x1!jfMSr_=~$ItTR0+GeD(8?Zqn;$(=`?(llmb3eNsO+oji`Q`Ev(oNJf z(Hy@=D`GCwa59K57oZfqvB=*2TLm)ejI^>zSe@Jo8Sj3iiaZ^2>wQoTGu#w{Xu>Nl zKNY4cG}(R0_2E720qZ@uXT&U5cz@g92_cKCzles*kv~su6S0>_ltCSf0k=Z4X6^~# z(e8Fqo}BrK(pT*diaoXbO4I^mFed6iY+2N5Ft^%8y8C(&JM^K@@A;9-ZiUyET$W<% zv*<&hoK3!X2;8PvKrmOtvu>Ny2&kru&LJY3*YWE+yA>dFnfr=kSfzH8EVFVHA^Y4Y zaZ(7Rfhs?oZ;mFa-HL*pT5T4&7*z_xHSGNFHxaXM|M)`ezYzS+3l>8j zzzn?J;9J3jhl@l`LSpa()aQ#%<%$>>#6?703|P5g(G5^`Ly%M1Fw9Vg=Rc4(t;J-P z6U3S>mj?oT!+x(TnZHBj58%y5^1uG^2}T1@nlC68ub+gEH#EiVGAc?3BgpfhaH zY@>DXJwJ#|U+h>L4gO8V$fNDyxcPZ`-N&9=L==pnx(rG@gtxUR zVxECbC>mm95)r*!wbLX4PEgDhBm1~Yf^QP(m2QD;91mzioYZWs9B+jHTUhgf@Tl?} zIkphb_$^uyq7|cNbr$4YUZfDqP(ZaOb!%e~2UYENV_kNSH>*f@RV{1N^LaG=qY)0u z^m#ibx`iVZtN4UAhJ&HZ?=Pb!VZDL;8&og%D9k)oq2icPLWhJ&jx#z)N&TWY3^kY{ zziTz7FMewp_!cGGfPfI~?dNVJe?TnhdGMdpF@5rkQ3qYQarxaZ1Kans*09c1QO(TbxM#u6W-*|P%LmdG?WjIwiT&A5GkN( zf}dgrcqV^8$9meJXnh4aZDNIrcN!pxH4XOlJ~7v+H59Yml*wVTJFnngIa|B~;)gsE78 z>@2oj3TOR&XlA4u%AmEAhHZ^ffY>@Fq4BxI+D|5MpR7X0)$UlyYJI+ocs_T6N=D#B z1@ct8^bB`_j8WWbRt@EV44ssdNZi!s~O=@A+JMIBTAAW zLk=K`ibyA%GeqR|cZ1t{@NzLW@Wn?al}*pZgv3uikLM7|u^`bJq<*(+1P-LA%jjK~a+fQ`Yu){WX< z171s{@CEWl-=@p|-ZP49h86jqA1cqI?`CnGhoML#z|4N8RJk2(Q#Qtf6O1*d2jqV< zBp$<=@aI@o6D=-ed5p&iUWU_8wGxs;5uG7(-bhgDKAQB^=Ula%u~*I%5~nCeH-&(B zS(0mo`$#eq;1V^1H!J+aJ%gWE4tZ8OICBVG@gC~h)iU`ls_Y#u26^>5VLd3!P+A;; zem~Mh-~45&aG;8xSwam<;y_PNfuh6aGC}2(U`QbePzkFu2UzB@h>ryHS+Lj+`Tj5^ z!95n`3@{AD1D>5rn2-eyT|+RirVyNA;E*vyXTMx=p0YB-(O~*18a9nWsNRvprl+lw z6pfD>2@i+DG9Aw8llB=Y5^+T$hG&XGQFa)e^!*G9Y@b+;5qiijimVm{!c_5EIcg_H zjk-v5Fbc&-HNnqM1JV-t)e`iF5GUS=_Dax0!Xt=0}D6t*3JGo*A`1j5gq$D_1ritLEy#NX{~;d?m(-p~xfl znqreph?VUcc&nhzIY$T+Ma#0B22B!JSImf(rwnWc@fxU@p{PMWl`qHrVvd zc;xrYto03(TrTtFvqEt*v?@XUQZhA)C=)fGm+hF_@y!ZG^hv*b!`OuIesSe3lAWdvTf*Lr{XEYIhXBJ>Y+ zuqgCG@^tw6ObRI;lZ6mX_|aZD?mnCmTRrrIgqmvDb`d{qW4Qe268l+q4S zRHx7UfIA?o_x-~E-%mPqA@^4G2$%PtgypY$ z;{p>hO1rt2_`jbRGJ{X>G#`bg{P(s=lObsVliu3@84ybX_ymdZk>~^V>d*U+k^viT zRy^~u*gr4!&rk5A!6#2}K57g>GOlo9{uFwyq?T6?7R{e`${_;!dKC>@sAoYhYWMB= zJkv;y?0FU~35j5e3ou(c?&r>yP32=T>_iO$shsBev;U6BHyGTVTolr>jrND#SDapV zb*czdvMKZ*&UT`H7<6>!%4ZtRR9HcJ_4KXk*31Y~etnjs`?{G>cKU zOSWCtXNuu!dlMRsibAk63tLw$K7q9SP4M#kJv09L!CMZslPFjKSJVZ4@`piybON)W zXgC24Aiq;oNf$jotj4Ok_3L@f)w!lDkM3wz*^s=dJl2N1%1#BCQX>Q6_i?l~#&LhV zjV3Daa`=82-bLfKTs9*ziBA-3WdmHVjn`b>+WH1?krC@WX9LOH>zvP=o-P(@)vAE* zL#!P#vj!B~bSNAwtk^YXACJMJsIBA2F#qAKZtfRV5(0Co{PWjY=^S+}hk z^HAq(Y?vAj$P1>-1|u#nDjxRfn9u%bsFmq^h95hYuPoI^W>#|!^vYaeGIVC*1WVnZjd%IpMK+m>qS}5vZf7dl z18X3OlZ?}DB{B)r27)}yiR|bY9b(cLTU%SRC|&a!a3uZfGbzWsVJ;utRc9J>PSaqn zWaiZ%+qSm1OE$P)Dx7MXzZZSHbFw*Nc2|)_$;ZB|{?j;&ZoUpc#jX9w=kq+Repd?) zWZ0)r`-LO(JU6n!1lI1y;A!mBW4^i>uu)iAUWVn*X%y~!y!6YN>HS=tjIo4Qi@eN5 z<6c&p`vD^sz1m=xDUV)e(UPbpGqWK!)V)DR_@y)>7m`#Q{pPW{xlD6r$(tbb@JfD# z=x@Dt-+vbU?iC_|9tmpa=PQ9g-0GH6nu~yY(1vW@hC!UKRqNzx7apGrGSU=-y}!uz zKfA>Rj7bl=s8Txta`&LDwq0(AZV6@Lbl8ZjyE*FV^8YrqFCym9!SUtx)Bn5x!U>H) zOSr;!ZQg4mq8tIR91%XUY_IqKjDrNGZ$))4a7sVVAl0 zYxnu=xgi>zfBr@0!9l11H+VsE{Nu!%!wzB=vtjb&00AOGAQg@R&DMtbb;j+j3WvR+ z+1Ng8pjllDB!_tuM{jIEYip!TGMC>A!zY3dE-3)Lhw(9_-gdPEm5e%ZoP-mC{z1>U z7z%Ig+Ej=O(Q6Ydu!(n%ch4V&L?}rLoH<^)rvF6SS%+{SCaVw~4RaVgrDbuhVftD~IZRzS@rr-JK0k0zTor ziFN`T{z!kg?0=jVCgI8oRmJo9oL#5*W>zB!*1Dr=R!^}RHK{$W&rVydV)|~c&p-4n zg?`C=DY)L`{dg5LC=dT+G#HlYO_7lx1`By}xg+O4+%-K6!fFrWgp|?Y9F>=JjiqF6+!Uia6R@Xo~|O zH01va$A50RorW+A#)x!O?T$kEN_nJ;IWkz%r9nZTB;)AwCN^&NYWK6iH@RhiR0*~W zNQT`$lMpBl%e>eEykFV#oMfFiFLcCB>&X&9^YOw>ju5~A!chtb2TLZ)da0xPS1rsF zoA%|D`C53b0XoR%2aNI7`|DFVLIX?aZ&)22V`jE=#o!AzYjoXclDkzkHIvd(3@A-= zL_8uWNJxGiR-uB1i^7$j_<>>eU-WLA$Yl~mm=9a@(~$$DE?9mtTvjBZBS0{SFgE|TfUglO0b zx(aF8)a<3}8E$hYh0i(mWoaJRbcw`aKl)^6%gR{U;Od|J$8P#QYQ*-7ORsZt zo-@MYa=qhr;<~8j1z*)6gWdM^$5LlH@VhAAh&XPoUhRiHKZUZb9)j09T4~2l)@k4> z%FN8HkCD#dcAf3CsA>~zW1W>G$N2WN8;@^G29d8Muw&C7?MUy=l_UAPcu0qpQy`N< zH?_i4wY;c*vW9K-X&>ulvvV`D?ecZ^d+lkd;n7dx*K6K^&t2`vh!ksN);n64RZ^1n zd@I)iuA?A%qG9}Zy6R8cO4W9&1QCe!hZ`Pt!iR4(H<0bG3_^%@0CU8-=j89@V_iL6 zgNL)_^If|~PDS)YGgEagEJb#d8$63;mN<-@WkD?)GJfj!?90vU-`y{d(hH6GT71e0 zPiMm3rv&wYH#QS&;q<6kk9!0(5yL z(t`MZFZUPz!F%#wTow6I2kbVt8H=$0=W+n^q%Gkg1S5U=H;8;;38xF60T{&Y?pV6h zVP3psW_sc>5EMgYME%=k+gODUS?&IPHE%ie1Q6jz3shxm95zWI#uyObpzX2()7)9dopqa+B_uy z{%~aTx;>5mBYfSj#_Po8=2GWmoFkkAKJQG8lTNjm9&8}7mQ$t0zaxTkR8JQkRxLsF z6)>h?25o)S%i-K711pQu7T;rsGQ}*msp!+dUKVeX;wlOVL`wU$-l&8G+|BW##4__S zNq)P%Sx!85>m+)e2F+kh8dB%qj`0u!5}glQc{y2tsb~3cW?3}ZT*_s;^yXcoXMMx7 z0?NGrKcHZ1j0Jbp1zN%=c->ASLI1WAAa>~ZZ%?9krpu*3or4B&fCXSD{v(dBcE^tB z(W{jRG+eGd-z9~RjXlHJQmcLJ^P>|i$Ek${b|z~I2Gjr9-s|85x;_bkyP9xK?huTo ze0x$oR-n4Q3rOywq6|ot!+b1X0(d~2y2xn~@VJ!FtCxubFiHU&Dq=vlZYSVO$UtlU zD8eFO0n@QM0o~ROA(jD(9vP@K9TG~r5c)z7{4F2|S~8xI0hBjlz+^BJ!CZVlRVt$G zajINj4*Au>IW6Hy2W{R%B3xIcE(ajiJorl$a^X2ZpW-h8ROh0`R zO~?H6MbrFJEL!Sp%Kp>fWk4=o;i^d18V;mr(JJLG*m|@%QYXqWl7LDC26ZMdry0TS zl8C01xV<_(t&*nxnd)^{4I%vJxg9p-tbX|#IW&EQQXld|R|jq%z$Hf(T!~kGs!$<2 zn4Fv(j=oqd*9gz}r<&qE&YR(jido&ec`X{g1V7lR@m#0ld zc1!F`yG&5sondz1_abfRiou5W)@kkDcj{aHlc%2OMliNqL>9EOfpmQa=vw$1uQ{HS0)i4AH5`~l4DR?}Hpjz3VU0TBD_M7qF)H2_E58rl!-<|32I zx9h@!j)B3;lsytf!g#{W$q@Lo-bjXSB=Bh?@JiuMrXY-XZu`ZnA|Yi~0*EhUWkSr< zxCn8U1RG{u-v17MYP77P>4$)2=SR2&h0kmaw`8{sVq4PPS~_D>H!2X$aq#`|Y*ur@W|U07fJ+K)ksv;oj@=Hrl`1J{m|b z&4Z3VobSDgH)`=mRsaP0%gbBvUdsG1*_(XeL-Nqns7d6|iCtIFykQ-Hb%a|X<*b!_ zr6Ri5{4W5EUD`uPLqRLrH%z5()t+B;ze%uQ;9J9l6Y=KX&L_)E1YuA)eE-~t^D5?$ zjIl~RAthJN-wGMg0Bumi_%`9)_W*O^FjaT*LqR9?+29`Podnb-3BeXD^b3MQzgjrXu2}aU6u(p!%U}|Fax2qN>i^lV#G&+YA|}QogKxt`mj&9h4_!`gt{`Y z1%wj~+r?xN1MGX&But03#q|?sI9CCli@jfxD_IHQSaq^82;EQjKZ9tz^4JQCeaQ!Q zFzmf{ZueSty!L0HIYg|$^)k~m2|#}StwTzGCp!vg%!Fj|%RrmnFJHb)(Xh{3V+Gsr ze(m9e1sz&TwSGqL(sZYb(!Q}~0(j;|PZehiQnJ9DOyc=kfGD@^Df?q8fUOjcw63ph zI`f|N7Z!?aF_u0@+LSNfav?&Dhq%pK0ESjMpB&_0agbVS#6W9(LhgDHRZ8Ss{f7^{ z!Tqb_MH<`oHu3eVaT+IlDTJWflyZtqNQP@41n|L>maMI+G-_egr<%TGf*DG(irp0p;+-_d3vf^;q|L9=jr+ca`@TmW zJ=v)qx_)0+Q0Ag8^`go{o#)f?$~L1qkB2<`UQ#0Vz$=S!aZnTSky7K@%V=ZWJ(w*O zBK5Ow6A3Yy-u^U$EvuF{i&~~U8)yOc$l|i&B;6+kTyyd|Nok>;z&=C)*cj~wE%pdQ zYkQQ?=B#8xG0~5*>ZH86m=C{~|K(r%bRd2PbB}97LrGz!IYGBfk?js!oEVWCMS)2#v4)cPqx!= za))J5izNU4ZhTAR3+jU5WlVw~=xA;LHFiyi6B8U)sCmBO9omOI1wWC1JAR#2= z!*jj!b2vwq7}W2>8ybL{R8dj`$l@Ux_2ps!ahc;!kX70Z@Sb-9^1~49VdywGISk(_ z=iCY)V1n=VM3EDu!n(ivo)WnTK(=$h?Zkn_(S5kwQC_N1>tuz;tospSdr<0m>t;6J zP=B)bTcgyd=W9h{;g{_L57h*ge-B>{x)!Cq>p<42bNT)I&r?0G?%0;7z=~CWKyTvE?Y$tL}EHnt&af#s3$XmFTZ7`)F`CxY}&$Zp$Tepy1c;s zay5Q9O9I2A2wjJ6= zQkowMrlyaL1R&0Ax-3r`ME0ZA9x4dj0iBgnr(0v$01>HoSpo~a7f9j&O_Z0Kr!avE zaYadU{^j+4qlJk5#$fuDc9t0!vqGb%hey)b9iW2EDf(~zwPHSoHO`fEX zQ3S7jF18AmtgL7=I&OEY;BGlb{W(R%?IcYXZWBw$=Uzp$&S^Qxj0ZrNQ=--Hn(`G8 zv}@bi+uIT7F_H}RQ3xtQDL}5UE>DI0!Ga$)MnJ%r+zNLAn#@#wVBR(WfOSzeN7&* zt;Rw*sKvrr@~-;Tzak;Fu|T{6lFixBjxd(e_C*H|0nMqOCeC$pBt&pW7-sW4>{}d5 zHe^IGQ5v=)>O9t^tn;uxMP_B-y5W`_c*e^DNQ+|=WqNXspLGV8=KxuQWQ~@pbWH^# ztx@o*g1puVwfwkCi{m}86I0h~r7y#6frmw9EX6emB93VQD+1!^vI5jL(LYTFwmjTT zUb>Xg*I0GDFajj>=)@vt|a zg1Fgz8P>tz8(WMxVl)Ul z3f#%xtsV6B&_e_!R(kHBMQ_CqM>`Tsz^=R7>(doJNZB4>(2YWey;)!ZxtVbeie`{3 zAmY$>c)HX`$|Lm0SJbN6=HZ}HphYPnDhPU+RALNvRh0)i)B2m`RA8QYZ|OoI z4y~3n5$5MAo5Yc>kuG+LnHUTrR^wcs4_}?!kr#~zv1&$O|F>@1cLAUF3 z(3naIi>80{}X|vNNha)1ZI=Czl=SAz|i-0xm%z{r?k!YKK=uPC1v%1n1 z?e;_jB*TG-e^4IyRxT#VcWZ({qW_^@2L*#tN9IXZpbi&+-b0M4&B2A^mO%)@cgUrE zjGj954Xcn;UsC8AUFOK?{mt~l7AH$|wQjiR?aR%{+!89w?S24vPC3N3t8L~2Na3W6 zKpw-}wF86{DJLCCx$k~{(*%hI#PPEJ1fk#Hh(wJmT}_AlOz zLC#xmKnI?w3j_GDGpoWgGR!P#wHLayDXNJ(1OBs|BF2FqYoN@wMG?a1^;@-JEMGxD zg~IcRn^mz>j{e;b0}?-)IkQ6)IBLroD68$SbT**(GOf#wh5C?IpM_AwDgSVGTJ#bH zMk7X@ktEYIb{m{utF}ychk2zBcK< zW1me*(|n?A59TY4-BPdUS@YU5MFf*=eTCwzpW4Fx>%Cq`a;Q@AjLADsdg()m>GuHb zs#UsO(sW(gJX8N@L4MI+RiqTgcnJd(qih#nZvG2EEJQT@GFUe%Rp2mT;46G@Hk20m zwWuP2t#I!K70%17d*k>Z^j9ghO~)$(K31-`?uN<(d>&X^tctY5B-dzwbSQ zl=m)a1s*+oI$xriM*VO*Tm@uOWFqrdUxxq8ot-T-HSR?iNrDAfrx)6v6nq$${~bM)upM9Ph2yU_3o zU}AdI^cba+_k1?G*bt)J0)gy>EZ?PJlMTois305(;G85K*nX!X)6=H-!~DB;fl3ME zd39ao&a(fpaNbSyXgwsZ_B{=S)(mzu-O-OrqTE0TQx37Yh160YeyLqwSaW*6zLHAu zID40;)7Wqa>&7=&4#t6}rTLk3KIB0LbeGmVP7y)>)$n9V7D>?nnU$NX=&*g zh}ILtxfNj415xE{PW{YL!Q{W%Afo}6gY+5|(m;Mn4wOdaJU0g|rNBh=@@(e)D&R4W z#x>q|0aYPmPdrmRV4W?D$^^WjAyCt7EI$^a+=F08hy}|Hu<R{nq&V6vuZ)iXtri*~|rUkdSEEIjr=Mxct3 ztXdaxy#;2ltKi1sz)VEkW74WAE3=$Zh*eKYZuyMXYyrH z7HJb;pgMtMHNVn%&NW9xHx+0a2`2zoSzf9RXo8}Pejwo^0+x&($ddaIQY%)bHHzQM z(}R!oKD~{VHC`LROy`HbUnm}{D6qB6y6s5>#9!_Pu4Y&Y#!kyqLWQ5kZ(VoGC&*QS zFw(cX=i#(ZCucV3BH;}`KKOC0kY0x0F;$T}JD#sbooVx`&@z!y>V#>Z1Ao1ZE?81% z{ZiYuX%f16DVVOVUjqezvloCk8&l~8AX7(2sP^Kw^L#AeZ?=|!X)7G2awk}V<*OLM zCctLc;rSJyD95lzAtfqMK!%NmHv)WE?a5cRjR2-wZ}jW6#P?gTU4Te+1^9>!sX~mM z0o^fn&ygQLJ;EChm}6HWgRx>o5)!&zP1V%=Xp zHGQET1xw4VQ3O< zQ_|mI!I#FH;X{8{%>H>#hEazD!uR(oYTrBFWx5-NF4xJO8UGrv^8Wn94^Y0<>Lj7T z!NU?w3H_jmw_zJw!Xv~i5h;I>#sOj4=)P1L$Gq9Oj)tgb+arjX$i%{9EQ+f|BW_#O zwLy z*buNj|I|HXFxN>PBm-W@2hTE+04eE>Ge_YyUw28@-`Sg;vpRSPL!-2K-?!c4lZ0!+pfGozDj=Y$4asBMJ`Y=ga$4+S6Dl9gE zK;F*a7~0N$sQ!*iu_ z6~FQ6`N84Z3?KKukPf{@Vxv(w8Z~KP-7Gl#!qoVVwk^RAkr5V`IjrcEnE8oh%k4Ov zCUU4oF(=Lrc9>Vy85aZYK^WAOHFZiLV*Ohg_U6IN(1_%6%cO5e20dt7uNN%=qD z4zI?W04~Lvmuu;QzJCi$AQ|AF0u!|g)BwQDf{Sw_wo$%9UWoyu;Y9kv5`@OJB_nb_ zXRhe~qqe(Jh6TU+$r;{?zVpoE2Y{3}^Wj^|&)zbJ|4bOo$NhSfQKY{#jK*>DG{ydl zvVu8T*6MxqZLN>(*G(*6GZglEJ^$rnfKh)a2}M%6>%LTEXt#C(f{cL*Kixy`W_nE< zh6@n$PYWwe)dmvTWdS$dfZE#o;ve|(VjDe>*GrJ^i?aYB}Ua? z-R;@TGzHAJ+Zau>8^4z0e?m*-82rtTy_izFy?EtqS&8r+`QZWsc&km0+XBMsNdVIJz1O^-S2Lpf)ow7EL8ibeote@`YUISx#KHwjReIFHuh&i3{4zcI7Uw%J6jUpt(J3T--?jr_Nz)dBgEFPy4`~Gjr6Z{y`fbgW z5qIc9Z6m~Z|B~(ivE1F9ySfHv{QU=o_1Yds$wf;o>F(ITE(HP>dt-L%S!%Em$3PTR zr9;J9+;}hbeOCrj=j|CYowyt}UI3_<#|AhwatU0(eeZxcHU|o&k-qDOFO+zavwBJ% zR!5stn!F9x%bPhZ4)v19Pt#txosL!yg{c>v!|lYB2H;J12;C1Tgm;zJ$v|f& zMhR4hpb@~vKgVfnG*1D@gOFs!M9IM_5tTDZ`e)h-K?K+rRSC$f%z&!i$)s%roaylya>@cYkR#_Yq)XNEca8GZ`TqBa37~_D z9R-!-E&zdzKxdg9fVuC=&0`^D<~`7TPXox324_H2POH0K9O!xM0!>vU2)aE$+(ZpJ z%i|%n4nRo9(7#i_XES{Pv0nGw1NtBqyA^R)(2`~d6lBBSb@;pDnNp>{vPnQfRaXjc zEt|!-G&pB~s6GPkbB=5(BY1Z>JI*_k@@^*^5Dh#uyFO2)VHbM!Q8yh0ID?@h3J=1A zB4xL-JxphPW15<=#8wr{dAcDfy3H?w;qOxLkaTt>Y>}h?#AnXKEuxUKg0KD;j60uB zxchLO;j-a*Q_ba42$Q*#2|yj$KniEqg3K=NP^NCG46kW>f3?jNu>{XP2B0Y-<^Vwa zrm$#xB|r!j3sHjtplmc-Wvh-RGAXCF2n;DKCW^<-A?K%njtmOG5N8s}s)Hs7k2&fT zP|+VcY=-6rr2t4(UjWMA5nJ-*%H?|Mgrp@%a#sO?4f>%k1RyCxQD+0_)396X#Vdko z1jn-+wc+RhM;ji}KpX^f(4XaiyLcB6Y*H1EI`U8~i^>9BP?<7hUEX->Arvt6?j7KJ z7#Xo7Z3#?rU))#in^fQD=%pj{n{Z5E7LzyrKC>#dfTWEna;D>j?^uj`alMCC(uH7) zI+X!aICa|~qg!VP@EazhrrKW3HY4P0jS3c_AVQGbd1e853Zx_Jm!V)JsYtNtDh9$H zP?oJgl;7iuRb!r@CC(0<0J3%6OHBP4wRHp(;;rEQurQ&sj{##C4}N#c;0CzTsp;tL zLO4m7OJ9f<&@J)*`+BoNnier2^hU$oV&t=&ceg&n%I`Ryk1cTYJ9wWS+Wc-VUyUsw zKCx|^QnV5FOQZ)qEXB`=`7|~7^!gx*gQlZ|&unJHt*pzI$y|;nyEd7AKJcp3K!o55 z3q^qe4LhQy+!I4X2F}@t2OV-U)0OYPW67xr7eQNW0DzrACDeQgY1IT33OXPO9vy$H zCVco4Vacc2eAv$-aD6a6i_5B>o!~sr#or*0`R&6cN1SEM$XDm5B0;CYIK`{JUlqhs5C+%`(hZuS1B zGm)+W))djbY&dTaJQDMpE_qam&!1odl3=5%g12YRi?(a79h_~kTE33M6c?8SucT!J zlEWkTd?c6neB9f#lH{hHjL*cq@Q9aJ>(y@$Sq~lAjXjNfuEu1=xTmr{a6%1zqEn)yVKhxYbDGmd33Pv&GqaTi@ zi4t0DV3@1_je8~2ThIGD84}!?N=p1uq>@dSI|Ul=&r76fF9x!0B8A1t0z^mEX?Zv; zKn)_!X>gv6R5D7RCX9enAzZWDs})7PKw?`c)%{3<(<5$N=ujMl+h`#@qNfOs zlj>h6I(w2W-wF0^Jy1nv=`QBU?L`^Rj*_u6r5WN5h=5~>z%Q1c2Xi8DdP(1}nd>eEILs^8CVa>Mx;X7XY} zifl@hZs?+VRWzX$-EU-jHfZMiMg){hw}vxHHb$|PWSP=wSVsFFKYpydP(va+MBI~; zn_s>mVWq8|g0$)>3`KAgF=j5JqB4HUeDbXS&VR?jdGHLG#TYonCpsXI3o=^ z|C+}f#i2ic@7T`HF3UfhPc|Mq`Da-Xv=*xpC4PN+{FY~+v8tqC4R00Z_Q{i=V5w@|Y4Q-KZmHzQ^@x*HuJB>1tPbS(E zdY^?~ZA`zNNq8eB7C*B-s4lm4zH!$n4o>kQG0lqkRy!QH-Zx^f`C-&}Q=5v1XO^Q- zp^=8EW`bHa(W$J4B}NNV+KDrO3IP#GuF3+HPY7ylf5J2h4gu;!bgX)Jn|y&ra|Wo&&`@bVq;FhEXe(8gZ;aByci<6Js(CbwR1e;Qw2bcRc!3&u#+de78i8bd zeL|D(;z+yrMs~DkUsAnHE7f`~(T`Aw{G5wSUluu`)00uo#N!dS!C1a%lDD$@*s4?g z3Mv@a3G_w;h@91wE0|%v6k}X#h{hJ-R3v=+ne=LC$$2b_oFmYwO zUAfhutjho9#=&feQ%b@yHK%}>RD(97d|Mnl&OMrR+;)w$X#nF>ZGeGzJhQLH9*@7! z?c=fN@Z%uTl&y{9KpmqpyS4h@*=#AA=NHIT#8ASN%>~*9m-l`A)K?au%xCSHcy9uY zMQOACv%LA;5tK2R07;so!&;4XXzm>n10lOut4z7DIF578JNex~RBkPG2QtCa%*@@W zw*dLJ2YxnZCJ9yi&yHj0#tF-3zq3oz(KCsuT-ao@WesLt1$VZgV_hUoLdkv(T zf#p^h0zvTd#pKvriAG5_Hw?|@MQefvZ83~Z^BUmEoE$K|O_OAWV3=*>Qh_mH2wDl2 zzjYu>U-r+oWY3tU)UZD5j_a6f?D{n}#=kL|af_)uf%Y=ztf*jswQRO%U}Vt+-y_AG zVJje)U!h3YN;dwP+3&4i+D>y!+Z+=V>67X{6>k~rKExCk(KUoePrn+AHg{_6qGf?5y12nP=5U;%LX#Rp^+%fXS z{8LZ!gU5`4dZB;)>SfVuwD{;FwCAf-6Sm|y8xOlL_jw)(vwQJQ}dho`&(j=<&f$0Yq*^=;&G?!X*F6B zKG=+s{F_k3Sbx}PL7xT9&uJ6k&e1^|T#pN!!fAJyy{A~+ou(J%)Dd0mIzBK{la($= z_DzGz-0kaMjR2=!oil^LA4MFh8rlTXU0YBm*>q8e*#MlW9;l~?OGya>D>`P7 zQ*siXe?s8{=ez#`9t1<+;I_@yyMq=KHPAB#0FFPnoN9Q=6PU?{?159Cgc}qmp0{(4 zCfy&*np{d7zL&Cv%hF8~Gg1?_XM3pOzqCjPbK}^3d?q)`0=y)wUn}t4JS|o6phc++ zC8Ed~bL(iIicS`ekhppcmBYuiImpw~Q#jJNU%P0fKH$1BNWybAX~145dw;X%+*o@z z2jnv05Xp>ZMAD$w%`&mLj7;3U7bxF=bM?5tNq_MH@|m5PN)*sj(F&5{A&_oB&V1ys zTY~595bYq(Hh_ZMDFge63PGG}lX&GE-doaa+-J)moeC zN@GDmL0J2h?-<@Y$f+d9$?@`^lb$u!YQP29BS6=lI^%O}b_^dJcXY(YQ5CLzpMa*K zppfW0IMDGj#`Hf6r^ty)8iAbERcYq64bCaR0FE&+_am6UAs!8Pw~fGT1t@nOdtT4X zci(T1=6!l;(B3&T0(w?@&MyM2U?vaC!Z5r-9-_rGXqbj8KD>}OWz)y1N2pqTD2h+S z^xq7aUIfxqB<+yN#kfdVMjb)hy|(ffOCuJ_k;c-E_<)XDV)oQH_Q;PXu zR*?dw-Pqj-R7ywnz|iK#oM9d4$`^Nck?mN3{5a$T$h5Bx**xMD+}vtzw1BMWGSPGJ zWEPa@GQsH!6Z4t;pb7-z#PeRjuET5cu#SxM4*J0aPWV^^b4HZom=rWgcD8zg%D0x= zpwHjG7nMum17};BDzKJ+DgI&IF$NQpY@tEsfPn2uy4LknYI-x-ZRU+2)9%MM)B%=u&^n05xu2UkADahF5hg;7+#(d zo%`y!M3|PLjaYC_$)+u|%Ie1)Q>^UXp=pnip|Wg|;Qe^b%i41%{rjRbC)E=l6ee51 zX>8Ovt;2BZpsHg7Y-f6txpD69?lz{&>9Co!=?P`8+(ELoFYI%Jv%+U-cpSzwf2 z4cTXftG{8F%-SB)%Mj7~KDgJMv8td26#btQ;5Z^5^)k%sbHrLPL=T%ce^;GJ6x* z_n)|zF`h7aU4|gNj!8}qn}KDlSroWiR|SjW1`FNu)5Arv-~@A)+WGm~c8@EDr15o~ zbBtOCo?jL2?e>+ms*LJ&Vb%*`v;F#yy+%DoLkwhM-GSwEueNKx(#Xhbe^vQVi;0eI zR~zyEqIY5f=VZx{AB=a`q(hA5pN*nP2?kvOVdack$FiPsch9X-t%F9CW9C&wLhvU9 z1N+xrG+;Lt99k_nu=ri*5E4U_ttg_rVVfc?zz#0vh+)F}V85(-0W}?Azv=(R&=4!r zmheaTPiOMIeYrkZ2HRp%94ab=fMZxguX-q=J3cs97ZxE=8E+HZpN_>}mxh(%z$O+; z(b@3;1UH4jTh1o?h-^pO9JxPh7ItU$NSGuN+3CRB=-B3<)7X7iz%RJP{XK&`=Mhvg zcVKx^^rDw+Ww&t;xJnLrQ+SS|3L;MMg9oZCwJ^A8NspPC#QiL*#|LQ>j|RNjOzWN9 zi9ThkJT2k+gI?PoBHbaKw|7rnMEriST%uKr1P7dZokutzOI5{4H#tFoN`G);*Mo&t zNoB*3iAvYN5i!s}qt!80?U+ljXgMD?gw3gjn(FiPdyF+B83pRlI6|Ou@*mrfAXb|e9%(tT5Y9a6OnQ6d~400>KlHiM%rn$Kqi!beEHO=i$USY zi|bjcTX}2Qv;DXA{=@I~T&Ox5H@qg7?a( zAg?L?V4iRU3j`-fO3h>z&L)um+!{k;z4KxFArkzG_30hqzF_AD%|ToAh%sL$SXA zlkT|^Y2yDF9Y`vwfyUvXTS}$uX{0-0jypt#fNTLfw}tB2=mWzNS4SnvIsaJ< z_H2`)QvA?juEMAKVB*Wi50IOy-;OW(XMRXazTmA@D_+)YAVH&`XyWZNBQzneDMMnV zLF-6N_HtnwUaRxHc^t5)mGi`XNsP>H2dM+mHe9+188Sbf#CB3Xc&lmj-dGx+OWsHq zyp?1W*j4iiMc?KKa9C}6ZG@+MwqJIxBh=nO++*nzfFxKlNlL-aQ&T#1bST|q1(~=N z%02%701jial3U%cnjM!TLG%~buKG)9TXuvdzJBj73C6JP8t2LXz;s_i4y@+H0j3L0 z;}dSpwS%`~Wg(zwxnzc_Bx|aVoKdEE-um~8NC<1{3aM^hly3T_mA%bz?Hq)<&5=1& z_4@m=gOWyxvC#{wy^zkU8~dima9@}OEu&aqwWG!eDSkmNN2x2>!79uX<_09o@*u>A zK4*UhdW|~(i#=5NUIzviw%XC}r|sW4{l{z6&hA&^wv_3)RWQ!%KRV6I&&!t_lfnyE zcO2=WuKM|P-}Yf@WR`t0Ix&QC*jW{a?+<~m;)PP=N`XXj&~ot-ko=%M3-_mS-{)uR zpoQ%K*ril?WdHR3=UcWhE*xf*tHY1G$J|FlvB9X`=(#v+cWickWvH>!mM-u><4mk< zW@SUwYy3h(Htu$DEM7{+X|KKZ0u0C=s1v~ZN1ZGP(CpcqD6QYdZ>2DSR+esx2{!@5D*;L;0zP+K zS65d^Ua`2p9|7tBWK>igy95Kk8V(8A!ttqm*G7K7KTOL+OWUj{%j*a6qo5R*HXcYp z=I5VVsR|yDh%@2#e z-kA@N=E^hl@L2KU^rClq!%)D&Xo5T#Rz5x=ud9*Ntm8{ih$W+=Lj>{@zlaDFko_2y z*j~=BD2r~e@Jct0U*tPz$_J;p&kSFH|V|QGXaIcKc zcT0(P=|^EYMosWJ%yNn-u)5WxE8ehF4u5WH1k1PLD z{;s`eu5{WhDLu1=(j1Y?0V&baNO%7niO~5+&<^u-RlT$&uS^bhY#yoO%I2n70p1NS zrA=~EF&Um(9SIsgQI~Ig&QsB|Vt*2?7I~`ID_71J5#1QnT|FYxADCX)w@H3^*LiW6 zt&#O+BG-K_=`k2SJ1TSbae zUM=yJsQi4oxaAmHkbVzl7EvYQ%kp|(UzpnPq7A{CvW=8L3=A6>$i4yq^y4Bkf>-94 zp5X9yJi`qj3%odQybl9Ps23a@lW3O7uTc<~->~~&ig$^hIEx2*$jZ}v2h1tnJDTg{ zloZCE+-V82$KpNuKd2iwdwP4{2naNtrpe|n7@3&#yy|Ue*dikW-1Sq6QEY1FgzlKs z)cb;`ukue25D)}V{JZ%u71BlU%bsXD>WHz6l=;uiHDr@kY>#F%IRK`5+WzYm384p( znfwR2-3^5gY4+oA4ysXH#huQZUq$i3Z-|*;1(qiwj#KDNM%Gule~=`!IMV;IS@F~QM{WRAs?q(&{2E>EsoSZ>+%&3Bbt zo~Z2IMQjE1XAcg_ChpmwIjcH7@_Hug|t3+)4 zR|&!~KSZ438EM4`&>8>ze!%OWKp9u^a-n=!o7D^%66ajH_Bf&{jeI>GB zJY&;4OIVRunewago7Yh(TUk<4uUJ1}Y@)IgT4}~(kD=8o%@~$(j&Uiea+RCbXp2~8 zlukuElylQ2rf1g-WIBm?5WW4O^d;0j=tPO?Lm49#4!~oE?)7AEvG*HZVw6IT^G)}O zU*Vxc+1YOI{0njK^bnwl^sVbXRNvrq2vco?UI;-n9TY+?U(h&d0Mh!&`VWZlEW^cRO%9>erL6?TW-=4W2)PU+x)Yg~-AR!F(@ZG; zeBzf(PFyixL=u}8WL@8%vZ6K08|Gp|DV~3}xe{W`_q)_@hTy!M z)CjAY-AF}Yrm^+t|Hs!?Mpd;&?FxdVbhjW~5)zy4?vxS`q`RdBr5i!%?(POj0qJg# zP6=s*`)>8z?|y&opEHJI9Cod>-Z|$}^FVTW>Bgdh6X>3;KIJ0U({E-nE|69(M zCy`?20lkvk1smK`Q4Y%tm<{x5>uo!E^`!T#=N>7a{ivX~w!ExtCy3^aNl6I@UBzI< z43N-vg3!@C>d<5=hRC!38P-$MJKC^cfnqouuv=BpC6O~9Lus#EYF>-kn3^7*gtcY; z8`!%F@2K;y{ z0gKjkAnW+q9WL}=hXVR}(Dpvh*;tQr3DIudOuAe4b_)W-nR$(kdQ)zn4f+;3qkIO> zW)bL9?k!3AVZAUQHV`JN{NO`X(M{ASWV3Gw;K*6EhrXqS04@ADTb?UOEFGdHwE)uavpFW(rTk@rPd!%_HbdIuxTdWgKWwF#=K zs~KIRNmufQHD(}>#RkpsU2$ge#H53!!K$&$m(su3r;ldUdHC9MdCni6DR;g}g4b%Q$x}QhQa(e9KX3 zX+@;?`n!~Q1wI*(_R|ynPK?!k|B{jtS=^qT0QF0cNrPPpms|*;&P5e{n?16}*|Kov zEM*S|JL)}pM9|7=2p!J;CW_q;g^Sr@HB2;hC5Ur@d{a%qUs45hz1w2w0)ar?<2UUB zRPzDjV?gslm6g?kGe>{Y2jtw;5$-5$Y7BpN=8&N#v-J zng`e#xWMCsD>!ynz+4ddS(dxZxeJRxdV!=s0Vg=fmO;ZR=83?uGAZRs1O52P3#EKK z32_jT)i~cv;h0~r-mNH=E~PU`2EL86nBsQH9(YR4^}l|Q-k-gOWm@rix^S6TwoWom zg#{>rY(oa*ii1sZP!F2;(e!W7tpBhD3dF5Ynbs1;A;0Py1^m@W5}a3Msk6{< zWT_}yksIecx5JW4%H)=Fs@%oS2KjshAWbPBM%k_=qXJA1aNy8MoE8}BrMBw`mw$-q zL!Otbh5gzQoVVr^ie5?~k?Y`$G}F-`0`jdWpcKQXK_EVqnFMNjsM}Rwt-Mq5EFZVrKYzyS~mqrklI(57$o^oU}& zj(lPgWgcJSya@?b+DgPcH7hblE^K;!Y!Y`$ZMPszTI~FWxrkU_r^(s;kV3&?oUKPX z5pPcHPQAQ3`$E`8F9^*7Jnb%}YvcWji3yCC9(}{xMw)dGR{|;awg_!-!(TM#Nnc`9Y?4h_EhMW~HoDAXN8TJ|`mSWICit~j>)6Fw>gG9WZ z?BK}AX-CqUM%C*u7MTuCsx);zAdYF#Te${y6XVqmf2f2|?@VT2(1Pd)G*j^i3=Vag zq9_x)ADh@kBrgq&i6L#OG5@tRGo$5UrYJ&Rkmka3)Ko*agI){& zBcFZjL+X6M9)+Yy01IGgVc!+h^*79^m5M=y7OGF1kknG?loQLKf(m$er&>W)>S~NI zZaq-71(0(+lU}_LwT>Fk1V4o$D1fQelfx0EtLn8v?|6h+Nw*IVYaFLb#e4Z4{9bb4 z->33Xm~TA4s%;%%sV*GJw)$w9?0g{xsdYa0aMfTT-%y2<-*g9yRp6jWHdHAfKk+N5 zVjqF;CmW=FnU7|`kon#@C_67SH1H%AiF+c;aTEFi!o(gpemtO#6y}HeZJIRO1eXZ& z=t#7_xQyuRymx`o*3U?%?wmn;rmr)3BrW%nugNGArNxre*o^=8OlEEX>0Gv0pP^K{ zO9d5za8RTJOW{#aa54+CnAA%l`cdz%h|b6Qlt^>u;yS-n zZLoPQAUBjt+lNEm;$yi^KrRC7Sm%XOj)>CfbITV9FxKOuMdtk>$PDACzb^)#Y|#R& zg|co&j#yY({ht!9e#GP|j>Neoa_a^q)(WS0&JkF;qk4#`r~q}yxZ`}_1&urz>ay&DfK!_%Vg_W++*86FOd+T(gI zNt$vnAIu*VL(LaJMg*_^Gmtwr2x(v_*e8AtGDAKJJzS4m0jf-hx0RKR4HImBD z1u?{`<+WU&q*14Z(C+5ygdIHdnY>r0Ns!yfOOb~Q9G-%2dGGQdKQ>WP@c0Ly~K}eMY?dgxc5G0=W zU?x*SX8Hy7I9lXxxQ|2nK;{0XrK}uH)d2A(tI4Yc7It?Kh-CUI-SdcdHyDWaN6M=9 z_pY3GFdprh$jF^PCD&h-5j$5P*d2wBF(`^-VII%S$&L)a$OuS9V;-mQDH@@*v;$p& zfwUX~U-r|2w^EQNd{Z`h`FL|1Oy0}reNHDmk=7)9apo359W z-CSw%N9c4u3-h~iIU5ZZcQ2yMOybIpj*if*g5%3w3;xt}sGKKlK30=m#2W~)d3IzYy6(Hi;%cWHuUPJRu@q@j2BQ?#LsM}wtNojA;zv; zyTzGfx^)SS-sd5nsryMn%bcW;^)4A3V%GmP*XrYd_-~AevLbhk^wtxOoVIJqlEN>? zKi$z`KPtU9+mDp38DP&6j4C56x+IyILs!wwIMb9$&wuk#YVPJo`w|p@Q<|@K0?nE^ zNO{ov10Ojb&TA+Z78Za!d4&L$UT|x4gIEd?G}@&SZ;<)21Kgo_`NOzh9KQS|DLZPB zOg5n^MkahkGZ7;s9d5K8`gJE(lU+JJ+{`3nYY!0 zEl1gLSKu)mFu(ZGL&usDwR|)XOCrZRE_3S!VgvA?jX#b2X9}v;q|7Y~^bs)9$|0m2 z90J~)%;(C8aO*8PDn}>G$VwU zG`tRnO%CiD!@ECCZ2wkB3&~?l`oIWipg#xEu$W<=(yn$B8`5p$+s=i-$LlwJ!4|bD zP`Efvw8=sSS&>9?zPUQ4-mE=Xl{g^!L=BVQ{e7~|;9I~B7^1*T@T75;r(gWcVOG~H z)qzLO6DtH7^Krslmvm4DKe2Mi*S{nRqM8mJoyXIe$)JjfEV~&qio?W^s7+uYwR{W} zg~g(|epCPp$Iz=Jf)W%-NnO-6#lZ8!tW%aDmS3X(t9~!1izeH9!YeFF;QxfZ;c~;8Ke9S?4xTS9u0gA z>3Vz?y$)bFu7&Hg7k%!E8}hzPIpgWnSLFhG91>v{VdTfKKs#DI-%ss>!y^tFtsO*F zQLf!lc9w%88+Kc5XFYcpfI)mJvKh}6+h(>D`Pf4HkyMc^vR9kFfc$^9h? z_wUU}@3bg)eG*yEw^z^_u&+VG`zuu0pNNMBdQ3<;$!aecynGijYSV zd=t1+36%UruH)a#LoJJ`lAcS|))t0*x}}b^)Mdc~LqRfbs)~(DhO_>QJ1X!4Rl47ksL_dJ?3WWf#@`s;oY-sl|PbHLS!q} zlp`$}$?kCQf>%YVV;Zd+pX0GRP=bNEqj>(1YPmQ(L$_|PU}S=DN>fTm9DQM@WhztR zF~?h-NX@##>k_7Gba|BR>fO7kF_r+FW z9bghR3+s}INC*Ez3=5e2osc{ng@()96cS#YH_)PHzw65|{Y^1S_nfvCE;J6ihi)6? z+x@%8`~kl)FTTAo4vVKhK2~cUDbOkAaRW?@I@XJbbq@~lCb}37B69L51adEBA8YxS zP5+C9SS5ioM<4#Mk6j@zUp$28>BMD&@%(cAV2W#z7uo#1s!8cRT%lbHQ{F5dRfQJ1 zwxp8(>o8AwL*8T{0ueTa9y&RGqMSDtIiL}EpEa+l913L3UsqOEu7Z94hh|q4T`m3@ zw+R{MNOZ&`+zOKkD0%~MjYf^oIGnN4FctSLvz)eD{!`Z@e>dyrqGUL_IjE@{(_DYp zGoDC4`t12XR*j-V@ye@K5RvB&JPd4h%lwVC13;TGcTysJo3&#@GF1oLVSB@HvR+Wf zEmC>%8kt5+#$^>(Uj@G(Anr|BLwn(z#cE-1zuT+pT2|sJU0itFDs34~O>-UyBr!{@ z19&GBumu8(`HP~_k&!#|&&%YBi*8$5Ovx$S?%S#D+WjA|a+|=mSgvTW`0B1~2##o~ zZu&-L&nJw0SaC6c%_BMCcRL~hb_eK&nt>z_uqkE?xN&ylFRo@0Z)#?A2NNE6x&x!G=P_1CGgO+IG{9(s`REq8Fnt#av$J zRFh}b32&ELCL=<%P`pJpyoaGHMLbXlhm_B?8+f-zv!&3xdwSM@^~rp)Am$*R&cqp* zL>LsuyQK(}DqJW=*&yb#B05EOSK+j$M_FK^nl~{gbjka{Z2_cSRcd@0#Q0N({--mh zaYl)uP4uivQwP#&Zt3}5G*w~F>Q;n@M~aXh&B{n8eaZx+d=9E&#EAVT#?I;Hzih}w zBwF8$do1sbQbo&oR>{SpG z&KI<`VkHKrjvpBm(A({QYLgzDmKF&dt3SY^84eKE9RhWk4LU;vGzJ;|!vyq#pok>^ zDJfk^q!T}o&2wO7_tebmjFB8GX))_es72o&Ieq*64?kST3=CFLjOtiWvYFNpoHhb% zXD!m_ffL~GsMMRe2ExnCpwDml+>Z@kdE#gXWASFC{C5hzfboVa%L#T#>0G-zNVZa~ zaoShrEv>Vm3TqRsz^ZD~VW^Y#fT3>uaC|t9w1$5F1PI7Y+5ddZAj}t^)@4vCphmQ{ z!^KAI6|b|WI`y^@P=)~nlI@J=hIx%3LN;Cuq+o(0^Y3>%W`sqV0SJ`50&BN^Es!PP z+_)876#qOS-b2LE=V7jw?*DC@uiZ`298cv+z=TW7xpXW2kUSJ| zsZla6gR0O!-174gLuwHqX7yy>a2B$2esnkTYrk)KQ6dHRG2~DM_Ku`FQcdeYn84Yh zaEIJc%P082cj!~?u22T~T~AsHnQ<7-9+mnf`g2)O*eRa^b+>oSu#a>;-nmC*W#vG5 zebuv5bRbG7!c;1fX<8Kk6lPU*cJg#|G)7}-2M{HgN?T4D4J=i@BveeYTtFq&kIY94 zie?D}Aif7Bss3;r8go-jMqS4GmULePW~z`$6k3q-7YHE1c{JNJH$SL*Ym#XoV4=%A}isCKP+Q!kO_l+dsX)qii8j}BsT;gT!`g}c2L zUt3#0E+Y?GtyIGpb!#ZWwnT|1$)w_F8baSY+kq75$eBTP`0OO$nJ&25xexn8QBLrt z!7=ml5(4dKHvsI}K&BlNh&==5yiP!AlYE_Y_848(hCl?n`ZHFF;xcn@K1R*%+K=yK zi42!Uz8lXq4QDT?3$bOOhl=T?mbF!V>Sdb%`;y8+8&TtYF45!+M!QKxbt~#zTyQJP zXw%n8Wlm%RJe?5q4gX9kFEAOf)+y+B}b44z78}=Ngz5cT(AmsCSLx79BiQKcv{;xX^!_=;dfzpSyldzMK=Urep;J6oD zZjyIM~H^i0cNJT_Lpi9m`wx2R5b%cNz|3L@z5xJm;HDu>Ql}`e-!a`Z)Tq>P0N>vwja&`#9WagLWj-j!imXr9+GtFr=NRPba;h=|M@m2alet)_7ImKm_NK zB%BlSjKMx4&nMUb@>T?VLcyrLkYUjy^1n*=!G0r2Cf3c_P$Ww`LPH$6U4R?keWk67KLrR zSz*maY7+bPSt~QS68NI}Hc>U|d<{>`p!DY0(^$)7>45nL0F~wg8o_y1oO>WAJA0(K zV7g!K`s%J3)vLMPIYe^A^ZknkC%V0!8>}>4nrvU?rEOqEip+-|SrRsPn%g#CV;kwT zYm^-?3Hb>GPtZH7zvI!@mqagk0eI+HxlY)8YNU^znNW_JoD{i94gCG#GW1bTO#iC4!Culn7>S zqa4#p?f5A1@g0szE$^{h+L>SRDSP@Z&@&XS&_`KZDSkJv$K5bHmOSD~Om?157^gW7 zI}eX`F7K&il%(Bmi$>~BUhHr_5KT;}HaKpECJ08=HD^Io1*qQp%@uu0(0C5SZ^n(Y zan(QoXVWd1QX?Rnm|(=^kbfckhixh|>#ZHmd#~|BE=MAg6P`)^%T5ZlS++GscZ=iPE#5C?m?# zivu&Uzt~KMF`TAND+BoCYfwR5Fy5_0XopBw(+SxqZuZV+yTpy{XEwvuCZYR0`~nyd z(;}cIVc-|D_I$MZS=F8edUE-PVnQ_|O0ytw?LE-E>qxrhzD$Fp(P@=fPWpI)=+p-L zHCT|$%J5-trhG)Vus~wC@z3z27u#_WU;$L3#XR=>*n-Psz*6+&&AUE|MdJb8V21Lp z6uUOzf&G!MNeLhP6c3FExgX!#G^=|wHaz?&5^UjHOykmy>^0PJYj(K5~kSOrD??KBthLViT^WB^yk1v#8qEX(2 zlV5iqpAUxOqc& zvW4^Jq!&yp*YKJ();Qsn-dSU{FO}9yits?G>67+2r=};Lt>+f)RSdFQ*VND;nKp&C zin9`cv!hig_XZXhOyIJH+IFBGVwGWl4)q_ZL)Vn@R~6{L>_+%cT{FV`7EB;kNx>tZ1DzTfh?{v&x5*1!Ox zwv3w03`n*kl#-OBWMDu>Kqu=4J9qs7;=Mm%1NPajUn~^zG-ay5DTdw^LR8?m$Hy?I z7e-ZEFA^zN$HXv0lZx00ujBNgKyXs3u#JezLU!Sfq^I&wq;(co<~&Ui)jQC`=sM4e zor^-6_GGlu%_`KE&@tP|Bi|aIUog)4rd;4Yk-P}OK{JCZ`f$Zlld9Z2F}1DYIST%x z&kHeSO$sPM7mA*Hf=UXz@)diHka&CahOYekB>L_SxwI}I>)xa&ZO$DOTmq6w@>X*x z3Y&N;W}37o{mj7!HqU{7Q1b(3&$N5_fwS(qz`YG0OcTAT!&qx0++=@jBun4KXmcY; z9Op6^$x13yH^*d0V>mAYS?<*?p*KX%X-54#k zL6k%cs+Ku?blr|@Q^bgSJplV~DrV+s|La=a-5$RRNRG4Aw%3*#+6XpNklV|C=f-VC z9xV3Lq#i~lHKDoYWUsH`@7g>1LMyCY*)$08A05=b^f=qTdpJZIZLeyhuyS5T=quOWwGb7i^vE1>j!@GB!&p^I-Ql6>&=j_-)cyWxLRJC zaX}5y>_PH5Kk(FAJtI5K)|qH4Re( z!VO)8JhRDn6kyHGR6a#ESzMCdWVAG^h`T@*z--}oHll1>K;wFi#`8n2aeT+nuuMVim%|cKmU=z0U5N>Ks-H< z&s{^wE|iT2`w+Vy?nWLyTcRtSaXQt-L(d#TLD=gLH2@PF?4dJz>&liiiPHI5P-VwE zYThMfi%Op@3}qx$d{5U`3Mzgp!~75(!hu2ZVA#XHX7~5ljsAn`i{^p|eeF7HLMWUA zJaX1x`w&Z7+Doeh6iq68DES9fJa_mal`MS;Hzkg<-xFn_6!kv-7Q9EmoHzB()8p<^ z?k>?47C5OXZH5FDh+}S%$c}ISs>kaHh zV9&dnNWXXf{ky0DWBNbGg(0hdYabYVv0TZRmdH%C%jv=ou_IGKRTy9+Kcr5WfKot)InoZ!F z(3t8m_NFnU^2fT`PQzNUv0lHtwvu0+hIS=rWc&nx50e0?^f}dF-JjR>1Bg!RQQR(F z7+@AcLPL9U$eITkOVh~7enYM_J}@$(RVLx-6N7fhmd8G}>|p|=vx)%i<>25Uylvk# zUkAFG$erAIn(U#%>C7fd=6AcJRoYBC&f)iKuHFVJ4oC@hioHe5^wJ|to%*%E*|MbI z-qoYTDa>k;)tM7+i<|nWHBXFf6K=%vJ_g;XsXu0kSSEuSR{fYayD>1P<|-;eA{9P^&j8#4__ z*gUPtetGgtepM2B7J&`ZQ6Qq`F;u`09HA9&`p{}@mx!VSE@mT~uY{5jmCbybiK&v= zD^KKd)@^mt($aLS9l2d4`Cj-e%my;ty$ndUBxU%_!kj&{TT|G%ddM#vq~MHQEVd2m z{lqe7$!yB|xNRp)%ah)XD}wNYS5MoPabNd&&@%HCuWJRxM2_A2oM%2>88t=6y?)DV zr3tB8_JnD)n(3nI!2db{kfF7>)wTWC^e8fYqs8iyZamtFim!B0hxl-Yj-m>OK225g zQ4yo7+bGQ$^XLsGv8D{E22F6B7sa2RY<$5s{c^T)fen>SgC2^v^BT+z>tKAWNhc$x zM*_vKV?^oq&9ir^G7z+%CWD1ilQHV1fTnH>hQUUTZO)6~jrY({#gMmEYoH{t&{{NWOjX8#p%*E`z&g zm)Qz%ZG45i7@4Im@i{H?v!Rm0-$h{DsA*|wF;EhJ@@d5E*88_jCV|At_ zRqO>3m0r<8gF}QyshBd5U8d(}+f9Mf*VEoST`L}C1e?6;Z2QwO#_gbL)wC_V)%pp~ z7lSa`d0EQ4>?*j)%Km}V3xJM!s*q`-_A2lD~MGi89;>`zMq?SwpFwPK;q zuHce71bM6yw{$&Rvbi?_>grJs6+YQKYq(hs`?l1EZ7{Zm=zWI?hyF#okpJ3{CgX#! zQGz`Wemo?_f?jo8CqKfThg@7HVmVhrS|}@*j_Joe^eMZ!y?q00(F9!91Y5(YVNie) zw3c916HRBQ>`YIC?^N}NKc_U!Dl(k;?y7Mm{`P5vR!oYf-;D#z_!`M*WfCLK%HiPW zW=p}U6;G{s!n+O%?cNY()jdvU&*nK{d|Kt``>?KSdj4^>T(;>Zn-5*QFw~U-dW$?P zZPi%dF0cTMjOCQ@gbj$*@dMK!d&X4J3NoZ955_W4@*TRM|j)d$=)Hx7v2J1TJJgqClgTQ@Ued{eqLl`XaB;gHSW z*WIsWb>S&?bAd-`2xozMN49~urvhZmq<}#Pm~j%P@NsYg0jk(wui-fMk8RaQB*BW@ z>a0bYb$B6{#95&GvN5t+@q7TjzyV)S!$xWzft6}KJIaI&Rx(2TxWEFjK&81Ttmg)L znw`cz@O6IqLf>v?GYT^;X&lJ0)xLnT40(JXh@_qd%Ek!L*^lB;K&|6(N`fJP7NKNk zuR7)AMflGi^NAw*dEPk7+~+`C;#d=w!(`nTd3LBrHbkl+de_QQnBQ)VP*e?k@g(rE z*Jko~MQQlo$7-go(!WP>Foso>q2S)d4?1&lH~A#^t!jDd6;F!sQ!{7Ud?t4M0dFKg zEy*h?N&>UI-UQfC|R;06-@NO$RV~LsvF7Mwx-+ zvrW4!dcyx37-?$bWwkTcFW=%7>=SEw`DV0>G?B2<0- zo3G@R2Vz4xwkVkwoDcH?G5MJt&8j*ae-&##reaijyPuR|8B=ntO1)|j$0=Dp10#N~ z7aV^#nH8l$TBE9^C4;%b_7@H_dl0Th0&zw}KqHCv1;Jp%&z|w;_D|!9+$QQbIzoL; zb!5hum*E1e5#H?w!{0tWcCi5U=w<$m5yD}r6j9Ag3KadlFv+gVn5VH^uX&xc*Q!}) z0AK2!-zI$kSa?8{>r!1MCx}t10?*#M0NMI>W?GHwfdI zf}$=D!Zd)+@GMAE2YQv;%;Z}BYSzxn@5WbY_e5kK*H!SioI9cKZ{DboEH|a#ncnJ7 zZi5XJ4DHMF29)=C#aJ(ff@w8I0Ue_PLXe@+cwkj2!V`3|aFDz3=IVH@>K<5Gj4F?P z%yDhL_db=Ah$`N>eERmeTzf zs{4$U`jKgImCoi{o#A9Cu56Gz(0^KIw>z3C7zORqQ=t^}PSg4qU!>)Hysx+2I_?|z zkH~~oveW3A_C>V2bl?AYt;O|(YsnWpMUfPS41IBuyioq3@gM&Xk)k6vX1zaE90X1G zzWm0!X~O5<(!#%q|CAwO&1BSWs()0~yG!c8na9F;jAC2!yeD-}0;v5<2+nh=1V$C8 zsYwrNUN?qhYt;!nMDVYVCGPVt&fmYWAxa+L22ogrpGX;)AoFIwD zC%D@MNc~4aHxlVAF|zPJE-2=vmuZ8X2Q|IvC8nru&M!u99(`Nt5N;VcsRvmA)AvE| z7=D?s;ib^&iPF6vnm^TUr`Is{4uYb6u+pTqo~5{KsPWIwe%m?&Xw}lmOwImYEpApDR@_62`JI*j=BrWL=BYI8CA@c2cay z+*fONHDaU*m48qYi8*EwFtV9$pIk$=vh<1oQ-1z)=tZ#fOOpi==M$$$#1Veu55M3p zz)m*DrTliGpD|nU%%4ztp!1Hs2yEZTw&9mx&1NIBP$utoMND>k<*o){{F+{Yu$0Sn z*PJ#%ln-XCAsHeH04a*1%#eG1$(c~<_zITHqR)2@&oq_bE$fq()@V;H@~fK9p|KUc zELQmVi+XVK+wQ98Z_Ui!fONhB#*3d`VA-GjuN@WMq2Osx$A7a6jq)p4i&qkkflk-G z;y5@787^(!sfJ{xtWyeQRmZtR7`y`xU+kV+T>7L8nD4b zOk;=-6IDZH?0klOGEaeLha5D~M?8&pLTAeZGZ*~iaK0l1sR0>^QQ_zXUn~&`ysIh6 z|NdPb)aifvziJ)8CPu6+4ZiN%4ea5Th;ghd5g8~R z=}e-jtJs}1h;+QEJu*jLn3J9XSLNLfevn$p8WUdS6EAN=n``0ScpW+KMnOD6!ZIV& z#8{*|QBX)}Bkad@l#uDf3qk9uU2BO;qnJYX8t1A*J|yKBb<9Jf++a!mZFTA2xesgh zM6HQrbJ2}c?fd()j)r?S0xIBo*Z%IJ;6SI2V5XUp0$2*OXWPll$EYZhS3iBw2Ma9F zG}jJ3`~8OFS49K8O<#NFj+|dQYsrwW15d#IY&sixKU|8RAAR}94fFA7hMHViXXl!d zk0AW~+lq{g4A>I>5nDYXjZ#^>QRx08%5i8PMDYI#u0n>6v>g$MDJ}7g;LiQAe+W86 zPd7wBf4>>cK?C02Jj>x5FBnw=4;4K6o%`jAa8H~zx0gw2sE2Z1jFXcpce=CCO-R!pLuMA*l#z`I<}wN{kN`+$r=$A4Q51YUOE zp!QRTDNG26AsP2ohj&~pXNPft<1ag8apCb@)?~n1WhEK@nu}(Z;qgRt5_2mhH3Zso zbaV)}TyG_7xBCcO94&=`epAS&+*QDP9VC_xNWF1p@83&oz5TPEO7@ z`g{o2J{M>49=FZ2vxDl9ftRJPUcEYS*VK@xU;&qlMPgN|5`Eh<9skE{fnK>1>E5P1S>36`gP-0i4Lw_M~6R&}7V2+`?AW{aJF#?Lev~6{j=cR36VBoCM zq(r0_aM59skwt16Nv^8$s-(#G|^SzRtix{SLlYLMwtDTXu-5%AMiHIdRA@VUQ-!FkLL&bc3i5>6Z2o z_*94pmDbx%p~IUVNVtz{AvV7g*Ll54?l<|FOge<@y|G;-^#E^@hi2uRS^YRez|1q> z@qfS(fbJ{?6+2{T@cPv3QVzcc){rd;?<9Levko@PgQbDUs?H4Q%CVM0|Nu>Ty9f4mF?upxJNN0 z1}{~KfsEuxDCWbp6_)*~JB)GBb=GS>#ym8u%=zaY-dT|G6O8b(50IJyfvf9l`rR|f z`f{nHS;|}5jM?}{4id(x6EJYNi6Ub^Vq*9JZ4}}8-rR$k4 z@N8Fv`B{)C?KuO9Id#B}@~>&&h969B#y4<>foeMekbMZd6N)ev{{sYidI5!J)s^#D z&hP_>hN>7m$&q(nBpBO4-Q6L`WvfwN*tCV>iF1IonQ{@oo`5%~jdUOziwLu19#|=$ z9oP8cyc_+Lp=PVR@qJWV18gyYVSBq1Tpm9Lpfr^j%CoC33T)9Kwc!xQ9EIs$IE@mr z7dH{dHE=?CgX|_Z84;)Dc|ojRW_-DA))ssi7i)Q0U&!74}vsRArd8-0xx|94|X1ZoT-8 za{l!ma0#9Ud2asO|mB-}l<af=wWNn=Dwj?%6msw)#o=UlzdUK)>w|wZ~VlO4eGA z<7yh{YKZugA~DgnpI4&w_dUm%m8UTzh5=fMCwR!x>|px?Dk%i#XUiGd+u@WDkVS>S zd8qE<_b40n?w|D_C7?sfN=}M5EL3i^{tY!|{*!($`76f{hBxRk4&S>d9zWqs!4C|2SG?+3v`;Iz4t)vj5(|+&k}`%=$@v_OfuYa+@Rhhpd@3$R1(pHXx0@3 zf-*2Ir{QpB#c2%5VJ7&}p45TiWpGS!-S>XzFH(M_VEA12@ANEH?yKXF5bvCuoa3EF)=FcDgiL2Ugh{*ig5Iuj@8^=36S?#H3ZqMuaS@3+-7gi^gF8JCi9XJIK4DzHqYx18g`E)5LxKx zlntU|W3h1X@EB&E!H9*`t*Cq{(JZbB@hO&%_f=7ekqz1R*dJ$LVM$mZFSPaSj<5zf zkdI`-4pd7eh#=NkXTb(VhtFK=Cv>V#7zAH=;(EYqI@{rg$~?|i(G@SLt=DV1<)8W; z{Wa=FYYJ*!3i3%*m}3+a-%6?9)P;GBKw-XUx2j)Vw&Wsiqo+m5Z0TDxM+mv7)7ACZ zIXZLxB~kawV>utc>vmGsUB8u11y`#)DyvyCyWnC})tPH?d$EkX>XWZTTYj-`?!RFQ z`ZJDgcwF7wSUMmU22Aa`@7Yg&qgj7nP(?_{?U9oYWE1Sp>I-ic4|dHxO|V7#S?PlZ(DYzMKvbax^;kQ+^XZ_GKd@`2-e+VJ9YY;CF<^K)q+FLc9b(5>)) z2YnI}5`uFr!4cV64TpfB;I5FJP*ev72IlzJFLg_;Jj7;2C9KxgskBf)Bpjcd_(z5X z{j2}#LLoyVBZ=GtlNai=MEx)38)cctzYPwG0iTR4p~sml_aMl^Ky31-ZbmJY*vCF0 z2RXV1ZMXtQNL}#=#wy%g9nUU6+8dsOg9BRszUvp|m7;9&EcTu8fq{XhWYLLsyShp0}*MK+N%5NK@DUX(pT#mvgey6NdR0fZG#YLPyL+&puHL^$=6))d%f zSoOLj%a$DTR|?A)>Z3(jCFX`uza$Q$uU%JB0;q6T$-Dfl+_2`o`9n&hQI)P+ZTg3P?$dgzA? zR(1A|nw-UFbNYZK#5SLS3cvR$63*r~`dXhptqu<6S48HeOS0kig2Ay#-bpJWVWI9-s>%cozIuXGohL@U74zoGaZ9b7qiJ&Fo%^kL@o+|@nJ0k7EJ6HNKlSb zbpu z_C9D)CDzx}`}(OLy6E3Ok#KA35xL_6S42YrBsCV5!A$=RK=9Ya;_+b9IvTt_Y~zHx z^88VsZDr*A6Ep|9WZmRDRLXkc@!SugB^v3l%VdbD5dCn+P-fLT_tMff*%wiVFtY5~A@$1i;UWFYFB$eYMdUz5B8AXkI<6dg3Wb;=W7dVs%iq53 zM`gN;Zx??0xWPLgA_l{w1gl%9itmnlqR7y+n#F#<``L(&Z6?b8<@uR>UdkZjceS6q z+ulDHJ%*iZudzPVh|9{rciOfXgl~EgJ@XE75BDhv{)sWFuBX{+PxgB5h33SfS&lu= zb_W*stQ)GS+-JWiXi!@p%IBd!L2d5D{u7Cx=(eX@dk~+F{pjCKWqX4o#Ve3YvLANZ zV_n-WwmFlW84)V{Ys4o+x>6h&=m#uelTJ~zNQX6qT_V0Or?@6#t%Yy880rrtpS^*# z1TU{<)A<(|0Kwo2t8vVdEsVWj<>Zvn)gx0TGaZJgO=qHv0sI8tHf?d<2Zr3hC^G8o z6p^Ky0;W&Zm)x*PRn?tqUgY!ZuVG)(2xt5AddL5;@BMYjO=8W8eM|`M+Z%Zm*OX^O zCjo}w(aG{_-iT&F;e6bUY0yexyEWDaaI)h)|y|xmXN_aE0axzU=79;5YN<^ybR0=+unbncaVXY?N^vLw`&x3Q_ z@&j=R7sBywAw~I&Rya{x^xTGU=0#V>H=IWLxX&#~tTT^i4%2?FA5_BUyBR;t_CDy%}nKw|}MU zes*9fFV}_?_EXQ#&+ie|UlGAQc#nVRJ^KWU?;ko^Kdvl_)t@eT?KPj}$M z6!U%DlpM|Xx<$7w2Pp}srlx{}gOxv#3gCQ7OdR}aqxODSzpz)gxT^B{))+2~P=!1_ z>HU}Ng}N=O{;Z#IUk%M={$m--o9-2ubQ`9oGxUwMch8Av79FM9nf9M*Y~CDulrYIC*TB^ z7Xji8^8`|AuP?EWWjy!Ta1PKNKQ2*F!Hn22EwTfg)! z)3Z!^LCOU2SK%4!`~L4ZFmMo^R*(jmYHtkW3jz?mXtI)7NwkB1qKsrnxs&*CAFJ@k zvLS3MrtDKhXqS{@g2QA+HvSOUJ^YZ|U-+N#;%v6OS6IOfS^fAVDuiykgiDfFU{=0d zqjWF1*7!7ITluwe=%`VEQ3kc@6Vx*uPi==0$_#oe%wcR!i_s@zO6uYCXlU;XFSX%J zhJvW8n$76=Z2m^x0KbaSVKhEhHTacofzjZQ?-RTLgUV=VdTs!{*aq8-}{ z;qGP{EXbh>4Q=IEo8R|_RTPy9h!Rd!aqib&sh6!F+T@_AjNIYe+>)KaO=%;LQ)JLD z0yLDmb8V6Ci7Rq|sF=9(84Fva(-Zk;GPb+Z`;Q6qZABdv*bD?4Fnoo6wSD(=+(YC~ zU?Z;24|i^48jeQ70EN4e?5~c;uLzE1Bb07CQS11;Ucz{>=1G*IOz#1kO>&B)hQx2q zvr~;h<t>pDgxbL0y|Gc}$RS}w-9j~_q;t?dane!}r^ zMes?Ev2Y=ygrk8Xmizwf?bX8lj6+$~BQfK5t0&)IeO@s880U6oDxU$(tF|WQZu^&4 zokDRub%f>BkO|jIiT%-J_avHNaIPLfiZ@j_|AyLSZo6kgq+R6Pc8%nD4^q$>lK8TB z`~P9;Dx<2}qO~9r(k0#9-QC^YNOv4sTDqlMO1itdq>hAicS(cNzJ0uJyz&0sasRkj zXYIAV`Nfbivz4nw2q<<#^)tKkM{Sb`o8y2)=Jd{S?|EA?foS75LXU;c% zOedw;VF4A5^J-9m$>xL6^hYr0^1NF}N@!tF0l_A=6F^s3D;k@!h>Y9(+YZV}=*pqZ zjw5y~QroU}d2~V%=|j9=9_0W!58tvyUcn?jxR6~~@0^;dFBcfVne>`SWBT{Nxx)vi zuHFpmf(daEm2kh53>GDKJxODn8 zGp0*c5VdpXj?32#x{LbA;;c#kb2UQnG;it6HlmSA{)Rfsh%0j+$?xu9eK(?WMSR*( zSLI*a;JX1{8R}_h;5-<-87lo>qW~Xt`nBC<3+_aFfKEZzc7dE+21uh#cQiRy`4GOs zS8L|8NP)vKJDsG6HOg({*U#MIwKb~X^-=^IP_J6Y&#%i&XHAhF>{I^KF}*&bvP~+h z=g1@e?vHNug5%_bv^_yh-zC}NZvq69gmLEswNf;G8_A+d?{oxS z6;U_9>BlPTUM}>M+cj3m18?mXjj@fy&6|gAQvN=8eWcsl=dZZmCs#O|szH`UtM5+D zLgbz0&|t`~p{MTmzg_hWCAJ#WqChpPws9cp-QcTnUFAkSMx-C*gYdc)^uri* zy<)>BT+>J5Xm@*a(?9$g25&$1Z>WeSzcd5C#41BvJ#Jy3J8uYi_ogUIYoBf^OXqwK z$h*C1Z=;5yc+f{-HqO`yukwNc^2etpSqS|5 zX>m(l40%J}n@ArHtUtCmr|*e-zq{I>Atm^s)YNl~l|*L#U`n zF_sl|vjrR~>0-Xy`9C)>h-e7Gw$X!lXggsa9=?v-Gdp25&NB}zbWzA6&F`v&5M%E0 z9+Fb0j4nMI+xqrO{qp`4h}ZD$Uop{&uG?Mt<{}!;zBZD%|#s|<^OZW$q2?&LDsR7Lw zCZFOqu0W4`U1)R)2b-%O)ggu&AvL?76 zaDnajuM%A*{0G!45vtJDz+OF*VlBGNmZJKhgcE#as4A2@c3{V`+WY3-0{1K5YwefG z%;_H=6uup`#~2ytKHdne+~mbDH39{1QYvMea-^y;aVrAWs1h`xA=emf6R5*wG!#H zl;PTe8P%)RM`>B}-`yNk6+aca1!%X9H2zw$DK$ z7VPb#<}P6^IT54iWwo_3A3u_P4w*NJ%}BGFwp*W@A2n)NqZ)lI+KVSa^%}e8;=A4V zOjpv@i$57$d>X&(e>5{3;~{I5!L{1Ji-Qsx)L(~fuZ&MNJ5Qnt;1Q^qs;rcnA2|G| z--rT_AbAwa2cOAp65EMr&E7#9Dv6MO$Tjr@FGT7W1pevr<>Ur&Pw$<6P&FuCIU0bk|JV zFXZ*u2d!REXQpaoMP$qN2jW2p$>Pv5dmb;pfkvLB@68TmRa@ z*Nr6yteu_=UE^Tcs>GAhi`ud3#O{8p&spK_x-5w(yuJoK zbZgBJW^(-lu=%e$cR(8eY3;N}Oz)Jmv~l)^9+%3cOT1{~=eLvCT=1O_(rjrOjEPCY z(^NJD6Ck+~B@6Mp;GRaiR-e?=RP}HHGgU`Nrh&o1Rr-r=B>`9(-;tbglUQ!-~y&E-2_6i=Y!-=({kVaSS?xRti#Z(9vjM`1i3Jer>w6 zb1j&r(%~dp8sSiCohTQ53}5&Njo9s9;8Vd*`eHSLz0%AH4IFE0*FS$zJt7h)%6#A7-h36mFC*z(ZkK>d+wO*GqS@3SR5own97tM|;m!Fo zxaN`c2Ye?FeZ@V2go&o>%JyY;N z13%;avml@|fWY{9kq?FTj;5jnux^h`QXWVwJ~vb;T`y^qf;$_>ky%feHbrLh=p*fq zC{QsOK`Q(?Bx1>dQY)5nayo?Ip9nqXrKoz>=TVjrjOx;{78$HoZbo>>C`f5l3HX8h zQUL~~N58=V2STRh<3XET&<%8&9Bi98A+vu9SBSWIRP^W2x%udYUbfLH5xbA2@Ga+u zwCrCb7-e5HwbpnY|0E8tLa314m`Ln@uK2ca(T}!F8-^b5 z7+UuxkgVfRDRaOUFz-Mqb6laT88I2T4VNT83jKzyMe{#|N00;u{GOw&tg3QaFTK=#hvoU)@&EdM0vtr0R7341iWjWGBmLKYfF@-Slnkn4Bypt`Y%w zBcTF%FGR{}c(xam{jb_^NBN53yn;QstieATAszCU_Xk)0`D$0B@?`-w$xVy9XQ@h( z?}B6%;bw%o&(LJ9#_!?aH#%!N);N_qJ&$8BH$TRV$P*QL>6EiciC?P<=5(Z-&1W#9 z*j6S>J{?_BOID{509f?uC~qV=zv|yJfNKU~o^U>@%;>qJCJZN=5zFw<)5qQe~Iw~!9mh>7Bf7GNW`(qW<}0E~2)okDvU%a(ij zC8M63Q};AoP;mHY1+mmJrP1m_45oy-pY;MEG$HeV?xddht8{*e?6JD$89|$nqj*vI<}HL@ zPKS5+0ALlJ!>!w4`rG4*K?%%c7ju&kmdvBnmXxliUfPErr|N&c+iDc#Jt0AxdB;}k zd?;Cw*EwWJhD{vQGiEN%^xX(Lahg-Z@p?NjFz|CB=*F2Mm?xfP#NU_B1RD5% z60XDz-~`63aNwZl%)^DZtB^Yk9mQ)#S^ClkSFBZ{93D<i?B5&sgsXUu}o#ar*8 z4SuVoaNv|OYZmHMpxn?R3$qG=+%Hh~!Bu%aDu_BB2UXj(~)bm0WBDKzj!M zi9sdT(ZJ7-uHax(!(3o~?%&96tNMJ`W7F_s$-Uw>)-d6wI=Qk~3H3LAOlG-;i$W{9 zusH?60F0p=WEkP>Ue|vW1Es2dxg?*CgJxmQALBUC3GevvhT2BWmYwap9ds7*6c;(7^}crlu0})JUsni*vUafEsONF5g{@6kNFHcOx?X zFj4fZ&6ofkgXcw!j0T`}Q}Gkrl+;w8s*NgK%p)7%NAPq7*iE>D&YX-;X1s!S+~-}M!}sJ7`lMXTC02*LTN|s-rZL_V63!8fQ>Z4v`)R;6U~<=;k~Bkh4-5PijBGke~19 zF$y#&3M#df++sD+NT#n~nn0E4lZqm`jo1K&K6q=*w9@j4M^5rD2AL5$lC3L&glZ%9 zo2woG)o#6;MoB!n43B-m9{d5gP?pKbH@iqlN#6i-vSk3_U?(hQ(wKd)hY?Lu=_M6=;9%K&R7J%>G8ID&LXklw zx1qSbawv!R`7J2$NI`sVIXf=+y!hv0Qu9^xi1A%vA{V~MBUzv|v{ixx#0WPlXJg-1 zJyXBW2u-4ZRPy1?!^yGrSD%u8&g3!5TyPa*z|G2=FrJK{2(!5nlnrKjq(YMtl*VcyKYjwa8qL8)Zg^br^#%e}sul?{MsRh`4HBMBDs z3k%~;->YZpn-?(x&1&Z>Iv2>h4fAPvUdnR;OgbK+4k*MG)M~j!{K_8UXPPD^sE-tS zT3jC(pE__ET2tlgcV#4ZURR6I(6u+uF9?7xvt_U4nKnD@NgtUQnk{F%{LXpp zbh;4N(;U$#ZqYdX`JqdNVk=aMDl~20juAf!&$z%hCwE$?`R6~L**g+1W9oan@35TT-GMh9q z$KK1fjDlC(X(lW5EZK`5oCofC;f&}7Et-+mx$j4R@c%q0Uq@L!QQ4%@Y4xEp^Qrkv z^gz329Qj%4UExaB^j&W!)Sx5P4L7C@0p!yinW8x_#B&UMm@pYH?*-bwMJ_EZaj)*5 zgxAtZ9YqWhfn-~>(pFIYZi^Jye+Ix)@ZE;U1_DLt7&%|cnws>&;}(i1rTt+dsA@?) zTmwf*HXe0gQY{fT4V`*u&MW_=kva)!r}X!qsFQ4gJ=OLvjLqX?ex@`hBEBRCAu<-& zWt}x51Lv8@j++HvnpKN&%(Ol27G2rLjT&U*Yny?-J`n{!UXjqvX7P~cCAMACyn5ea z=av>Ir_-Ot-Z#+Yo!#dxsi}7ge<5t{QHY!JO0P;==>qD0M*bIOW8rqg3U3)hk;!B3 zcV6xtQs)Az+7-(vTvjqqXH2EzZrHRdT0w=mQnb$%XsKG*o@N70{F2BC;&(oGCgMv7 z2Sj-Q{wn?Pq1t@#JtE@1r1w zZp}+(^A`y@AFhp8b~uI}<`f;}9wB1X^;{&0HhYTsTQn)>eF}1N{pm9Q(&K`%t}ep> z=hbwL39n?vN8xsmZCP}4UcUSBX_=6}TI`QGa?Weh^VBKJ~(66`*|?q4Es{UqpYCp7up-;)I2%?`cj}WlC0ObcTKCWbm~i9 zK7+!wu-KvE5!}-XZt*EG!@O=eAhkZl-gBG`yQ-VXN_|F>!o`T79+>8NucoKQY7yNV zOM9d~;JO!iJv(&{yYUg)ku?8&&WQkP$6!rj3o>WUp)TN0=O!5oi^}Uvf_trT_gc{# z1xPcg_`Y}&`OA1+>iwliI?lsV3nBox4*PE}MF~AAwFNbEdFye+}9}mV?610J6y!4z^3y ztC@J{UooWnRg+zGxg=B`8NGF&=l>`o&x(VS@4hUa!mLM+3hSW|{Q3$9$U~&sFT_M5 zb^``qe!5?> zZ1hgU_jlWoawj~tNp&i@#G^I2-gyj=B{){9M%@?8+7orQVqho9OXGV ze3iK6!8ohOwGzBZ(v&7~7W$o&(iEKi^SQleL)R#nF41p9)_KFCSpEer+Tul(ssRRt zxiH6yjoV?i+7-lT?H&0sfkQK)Z~Vso@-t9gmfkZai6eV^Zb^WAu>9+c zg$kIz0~3{!i(E6?cUYV?n6Et##2B4szqpZp{xZ!2_4rC2O*di*S@rKrhfaK?E#zJb z;1b%z<|CK{a@;Z)OHyj!T9C`V1z*yR#AOEVgwKMs4Zxt)zX3{A$nMxf9*p2~Y@xX4)YSdzND+w)cEJQ<2J+-Weje@uXm!0-YO!7BN}p^@eo84vZ$*5ubn@0cl|l1o^Qgt|4_6 zxl9Oul2F9Gr9MHF&*wTq<1-J>VWn-;DG?ZIL}DS$Z*P!t<^4gg<`T0(nlnWQtk&TY z8c|n@Ay{3b9N618fkJJ%#2o_rpC++ST{kGKh<>MNy4D-=W|}EdOK~jj6&}ea=Gvi) zCCcK>=y_&xSP5 zr6c}7F@naU8MhFS_ED@a+Jn6B5BH2aflvWLLUck0VTxqAwg zN2-TBrAF-3w_?TX-v?1znSqAMe7Iz?gema;BHO03jE#8XjE&nyKaH*{ioEL#|3Y4- zziC1SU|^faVNOn%yaE1B+?>z$>D+*JJTp|+|I2vNi@+05jSk;Wg_Yf_XG${hR-%$u zVZw%$_i`5m&ix@idr}@90E56&rOD$HkNz)MrV41x|tq z4Y0)8bk@~T;M_)_E%`SoO7hiiZAF2GMqzfZ=*ED~L^6EyjIkXgJrP$o!(}T4u~Udd z!kW@N9$t!?8jOc$mN1;@3-2S`=$dd)AbSUE@ zpxU*I1JkzfB*oU42-LN0F>m5Fo22>drT&0BrANkTt#ici(s!AKp5>JHOSC}Y`g8Sj zv%fCui-th78tDAD9|8yZT3SR!eO;SlUF?{N({%LBhSX_o=Ku#%n$*not}5ca;Ca)# z4_$s+TF;)FfkSN%{A(-awT8r&b_oa-$9DAGax@&ko49Pb;Jsu+!vIqdNs<(_bZUkz zqan>+gr0_L$Cb$ZCje{l-`~s^Kt0po--i}V7kr2g>N~XBo-VyG* z^Bq;A9K6)!x2VWWUd(>mmwAk_hficsXJM&8BgHpa3NppN)0QN+ zT{bEudAS4$%5Xl=3G+2#1a9`ed5U2n)xrs}Zm=3#w)0>!Sn6}V&igb1N+m{ zFZOLB>a9bFE_n04?*IrGObbK%O1dXoRjtz$=GG6)`1#pkj2M!v_9#A_+r$4f5~k^x zV-|nFG5PM+e=LL^;4whz7^-WnCU_Y|(_??W`}S2v)c0H?l*H(B-x|lPw}PMb@b)jR z)xW0qk;Cui-vKpGnD=pn1XJ7sj^I7Aa=R+tt z(inwC3Z7M1i0yZ*z~dSCsC~9R&wTF)gr+2*9;${JN&nYQBr-@!l5evR&t58}am8Y! z4dAA%X=aAgl274(Mk0iK->zC|k+8!5^g>$ydVm$0@O6iuEGJn7ZTjnrE8^lVBSAnr8!KlX&OdVUCbvg9xXaw;L~*OeYtOFTx-LL60p%$Qu!u-(OV= zb9{#s%JA#1Hu56J%PiNbQSUoXi;@e`JwomqrP+sJM4P@v;Wmsxk`t*wC0@>M3jPZG_a?ch8W@#! zT+e)D37rjq17=8Gy&x^R^q75B`Sh;f4hIU(kNuGu?0S;CrR0=uUn(VCgoVXLef6vQ zea!ec+i|{0rF|o2jgif0f8zY9t^JwArK>StB`qgyqNvN?E{=1nzQo%*<7 zwG4r7>?OJkZuTg#1UIVQ1=HtQtVdt?>9NuA5~uHG3+A>Y+f(FJDQk-z;G(@Ug0kUV zI)715GloN6E9$xni+00ww;ze@lE)#JHJmwUC3yIo)9zk?k>&cltQE?&P1>@M^v{^U1uR-)E=m+7NllS@hq0{oy>tdV$gIga#9nz}Ue_Jk3fM0$SpiP%lWuSwKkxu}qXfT{j$eT*9DWJuqxeg{33wFMi6sH6 zfq$ocIsPsTqz}aR4;wTZ z2mxM6HQ@;X`_#~Ik|{UcwV=y&)Z$1a)IJs~D)U=3A$NXH{#6*wHO(Ho@<^9xgb?OE zQB1<1$S6$UQKUvX;c2SYyY}yq&+pOa&50=xdS&C3lC~}8Yt946v4L5i*joLwInRAZ zoKs6D^yI$|V-g$G6n3giXK`Urx7KpA`G1JIhxIef=rGwjtHdNZDLQU+74vGa9C9`x zUJ~b+ugHMUH=ixoD-0MG=EyuQm2wmRamL$QoPFn3)c+*`Q4nfOhllZDRX?EA967-f}hfMx@&^ z&$?`JgQ3`Zf+<_FxVuRrqme-!If%kZhy#tkHI}AZ}3X+W~%uBmWIRGfcUy~KPEBb zH_QIc><*f*c}~W?jC&?F=3kgQg#ORZUYF0ot;J&I$#B~bv3zZn3<<}-yD+TcGJ<>| z<}qS0V;FGxp;BB9;sL%L)5U&_&@j8JO1|<8?_`YqTUIS0{oD#86Tq5LTVS+PsO14KTu9kd<7gColCCyrxY+|-f`Y`V@wv#+@b!dd>QbJB*n;7L? zaX~1UC5)pV*RqYj0nuyzLY5q8c@ByJ_#0KDYQ+y**OQLyO}dQg@gv9+OkWsJ%*tCB zKe5vAHMKQoMUBuVDN(AN?J?_}eQa@fTRou{G<*GN%`cZ2bqza#830lxCv0P6PD;6M zTnb)eh3tjBzn3(-&oMOv?zvCEQC!%~_@VIxA$0;5Vyb^XVj%82R=b@g?lPJuNd=yN zk&2n_l!$NkSM4MsAF-R5)jXs)np8hhsSa&v5dUEB*ji9_#`pH_YB1HzbNeFlu5&M* z`v-l@NnY023f26)NA0!xyX#(blmi}VEC&YBnPqVSj?d_yzhx(*`x|lI;(fZZ7PaVr z3g&;3k)5^oJ#Y2ik65e|{uA_FBE-aMvQMJhx==y#y&@NNr=RWUIC!3$>x1N3uE2_` zSBu1XiqsFt^h5^urB?i!?};~;0?l+u|o|bZ$bWt2u z)VX)7#qKjo=+=D@$xRIHbdGiPu1qzs-{YN}?w9i#YglO4UZo_iVi5KtN+n?lZdZ++ ziir+A@9_ni3cU+npUY~Rw9`nY(E`HP*(>>Pg@!sL;!|^ZfQ{Klh;T#rtX%!Mq(ObQ z<}Bdt$*1*%$F|e`9(;z@N9fKGtvP+vs=T-#0*xj*dNjF{UCto2y6!jcIuTVPNJe#| zO>~F8jgmix+fZd?5>w?)PJaj|F{JN}{VR0MZ!FNRUg2tT!jzH6jX8)(_`}e#dHC@- z7TK{qd__>+ZleC=fSK>SVT_2yrRvxHTr1@AUEM$Za7sTsC@CBHsGu}Wpq8{751VW8 z4i0Yc(Y*MBY?dw=EiHU-@JRsnaW(rGS@uuB_HF6Ez3s4WKyFoO)FX^DZ0Ui^$NN4( zQBitP@^A!{RJ2`{^ZT;6L+SZvniRXfxkk6HOuhTDc#1zGHBto!MVUSO?c6X@v-xnS z*p=K=mZGJkhoPgdEL4(IH{2T8gb~1K@5Xxq(>?UlO4tozHw}@dqF6!)^`yv6&;2>* zJ0jDu#waYZORXwp?y^_3yqbI{8AwS*?>emGT$)Sbar~@P6f*bJB;A_PQ_ZyXR=*{1 zlLlxC7Qz{xu`{HxBOGJU(>x=fqPBK7EuZ}rYJ%@w?u0LS)L+A0gj2Bq5Bqmh^Z0h3 zA)H?L*gG_IZ!SC9-K@>DbO0vl$1O1T54{DzUg#nzI_0^UXebQSqClGu#9)fUl=>Wj z-|3{3vN0x;=bwF@;=N)VoN>(fJtTp@A#(hVpqP&AWj3slPw!bNgqm`4b;|rji!{Hy zjgmgns-I!X+Y&U19YqzU(ES`Uj& z197H_V#2h&I77cD0qCke9(YD088xsVR_a1@eGXvTr^8!M%83Cz!UnhKslBX!;QOe0 z_vgtH_9G991~pR0*?EiQcdrLQD5Zx700pFrHfNk^-sW+YLU=2-xBeReUIaGu+;qy+ zOqLBsjFt_f@NA$?F=VEuqo2K)X3p^vn%XHlHqmlH;)Sc50=9wuWLgT_zhWLu=A*#8h9W{ zKNi=fuZVnnStzqJjGumD7WG5HufgH69}J(hYbCyAu+sWXa>D#MK0V?VJ{*PNEH15) z=3RV4&Bmt`^x+_O2B4`@_eU*OoIhR7kmF5po}(pB#!08_VXs=^N3*))nI0;$3O<(+_TptM zwYRU{x8-3@r+f|ieQ&ny{yw5n+x-j)PzE)smgUiv-+DDWINp_wS7X>)9t2rsPT@>s z?vYGJ=sh=!v*p78PRsXhNH4>v7zt(N*quF zm)OaiEo0IeU(;7CRHc`OaQN~l;(nWNZ?QMlxPHj+!kES)>0T-J%*|NV<;@WbX0={N zb|Yc4{Zf$Ng}-lAJ=JV=Y;o{jrqNVJ_?jC}?d=m+U6FdBW%}|`e?791)nJmlx<-~` zt`$4-dyUOwL7f1o+H-#b=Nv3^PpPaqb1Y))b-M^Eq_n5!e_iPFnIIfJB3BQjuW$mX z%e6XJT3~KmwQuzBED!$k-YYo6)Bdx}(SfbJ=EZsqK((CxQE$#CTNDfY;~tvOF*>Jd z=`RSVut%5k%*_NrpU|TaQ9id{7!7P=p)32Vpw9lh(WLvYDn*t~NljUyE0^F^AN7!W zzPt}-ZhSO`?X+L()^KLqO(prT^rhudEovkYQTTAg9>YF!=RC1DHniz~7KjQ(z*7tM8a`fQw80_z_ zzcFG3Zoc#?#ZC#@HFc7!GLk2|`(x}#PiJMa4a~%THdcItg@$43Wh8U%2bj;FrQ9op z3_*Bw1+dRen}&i}Y&adFR68q)9rciOoL>mU=%p6#@DB5m0GftHdq;>Z%`GMpWH*$A z{A2Pc_PEtGrP1{r?b8u*ihmQX$Fj7|padG5BRx>XO1X@PwtwOGSlu0h!N;7&`qg>j z;)H?D;>yhl+}>D5cD^z2){=I+6EC3NnnGo~^mZW}5H#tw&B8zc(0I^^EfUjwayNX$ z=!~5p?n~Qm7Ry4|%Zu2j%R(1kk-b8l)y92-WBG#1#U!De9}58BS;m{QO?R$7NU@LQXDxZo z!#6uNX_A|8y}~XaR6gObV-$7dZcZclCk{PP@hy3W)QZt=l)y-ZU%TM=L`1s69kmA@ z;H1n9$=;19YSEt5ocz}mV#^FTDIK`9*1*dbbc&GEp-E+3wSMcLIQe|+D_}klmq@-t zC;l}@)pxrIx3?V)+a$UfOX|JyDOt{x@6aZv4aG9sA^of%RGe#TqziNK_8zxSq7)8n zj63h)K;cbqrosdu#_qCvMd4Ys;;Oln^r097Qih-)o-0o@7YAGvLXc$oa(+!eJXSJO zSg5y^1eA z>pSm|5zE5lWaNi_)fiFX!S=@61zP`CmO3IiF({aX;+f-`haAt0;NtEh4WN#(i z#8xBs^cQLO`As_Nzj}_6RP?`UqT%BtpO=^;35X+(0@y$fCCpT7=lIU+eA<2(EJWVe z7rEMLYM<&Bb%7JJ)dsa;hj9wwlW`!0Ga_P~mKAi5@>cScv|pVtYWo8hZVq15C`~CT zQ>wK#qrnyTxNrc82TqMB#lm$=hM=4zPbvAg3pA5j3@TnT-`&3m*9%6=wtAez&@>YF0Th(qh%|R7g!m!@w1qz@*!JTv zeqZ}C9nkj;lSAS*=~1IplvVm;)pGqdoMd42=_dfx8l&1Gu86Ct9vl>Eb94w!-sK5V z_aTxp@U)YJcf9#C;y9H$6+P(VnV`7|q*o%`DsnjC`+K%+wDz^f^sH`d4G%ogr`F6R zyYH<5%`q&5u48fp71Q3zDvG(WaMeLH(ZvhQMe33BXXgg%8azBuR|5KgqVR)e$QzNLHA0Z1lo2uIKg8mBU*0 z9K%9cnQv@VkjG&Hq(#+S7cY0;D)yxXQTrAFi4SpKr#wLiw#c#)cV4Mbj_S*YJclcbOW1xTpss)FAqUzu~KuDT1YD)6iE z%0o=m)83~Xq1$!86({a^U~hjwbeqF;bo=ixep!9X48S6X!;Qjb!K0(icP}(7}izvZw#a zOVk}d0Si}<7vqf@ASGr#AFc}SIb+UDN<6Rvd?%oLAiQ9pd1(mllubB@oUjwTbIiX` zjSx>h>?7_%6QJ8BkspPf__aNxE5M>tUdy$4h;xH&Vv{a zJ8}U(d3`xu2G@!R&}Su&XJa- z$L%VzYXM^w;Xrr}J3`~MUF6CG+XE0gwk?-O>4U;d6jH0rVl-_5X5 z_CqsK2a{$gw^v|Gfv^DZL^n_X10vXtTRu28pEwuYXVVaPpetO21^O-63ur)L&#e^TTN{cYcIvC8`*&UiHj z(BnXOpn|4Fi!VKwIdzvkZWCXvP744-R!yBIh)n#*zrFz!*39J5tJ&1#Ep4a0cd0G( ze)GQf_GRzoVaUZeqBITi5N76$i_YSV(q^B`zw{rmByc8B>5;U<5bo)NS$f9OITnmD zj2xcsKBy_rG`G}}NbxDj`~kw39-2-osmb`yU*p*pa033_Wka^T1*lhil~7r&Q4W-Z?BeZ6iu??d(OGwt^Zu--`K2x zUR{-jUTGwuxZI1F-pfhk)8+R7-1+{je{yC<2v@zbU43hQvD<&+;?OxP>S~!}9t1QH zPHF_#pO&5(y5o|u6G#e3_H89yU4+2}&qp(FhN9w_mRGO5W~x0Uz+ygke@_K8fCZzL zC+6n1WwZR3I7WeTdJ!sR)WxI*k{jAifRgXw(?(mEqt{J-`7ILk`*fScoNq#hNotwq zqUiS?pJ=66TLx=n$6PqdjwP~RMN*|r?C(j?Q39is>Z=spaMF?zZw{c3xzxcTWF(;?7kKu5r;^ffPb&|e;k|oTd%~8yHLkl(Y)*NkF!`Tb@qA9oU;X20K^>3y3 z%aDBL*ex^9$ACP&w(isKE!N{+|1#SAUjRHz1fM6x0cAq@#mICZ!sO8GOxd!#JA#@D z$U^pz>^J?Kk3MgTQGH#8gH)s3^caa8=YV4us7A-Hfwp7Wnxy$cOlgvQJ%m|ZF$2|a zC!>Tu$^j09KjrkYPizxeU3P58Dp2oxu$2!y0Rhx+0g!TA=%~41>sx7!tjueH!p}ld zf?#r8&=IfQ?kP0{@p97_r{An*6uG|pQgh*L#!nwY#t$(N$qVwqLA63K@!5AhQp`&u z=*po6_=$ysXj*GXQe&46DDXDtTCGc}c#MJgOKM)fx=~DD%^0iTr#!?@8I2UoWb*pWExzkonI^xw|E? ze^ku~bf^2h{QgXO@L!?^{OmwCpOjPrc;)yJN@msD%;v{;Lc+*DXTt3&qmQkbNnQ<; z3n0El54|TtIC6KRp+vd}%@C`HSGhaGk@kEeXle~a4Z282Tx;6ujO=c_S18*B<+a^A z;A}?efpzx57)k&a!=lTcAz=Tqw|cTR*xWLXDTQKp(dKpK_795F10@e=u!}o@8D;rL1yO5J~qxo zDxTHw(j+unc9Ux@`rS^RWAqt%Oj{y(l8;2ry}}nGD}@Ppphxxg^-)E&;YLrIsG1VG zG5;mK@$<(_K|W?5)~}OU5o|{1ZNJTg2mWO^LBRfg@_}l2ggnm{IFYoay6OMrr8Yt- zCwm1Du(5v|{pOb!(V3{eKaohO)~?&0}DUJ(;2Q*I*kUbr1Jh|vR4 z#@Cr`#_@FV$?})tLEB@&5!-?=Unv+3N%nnpYLmkvN|nsMi7c@%M;X~5^Y>=X>S^pz zL>Liul(~1DfuG=mk<+<%oy}TSs(obM0E*||+dPI*SLz5FpUCj4f3%t?5wN8dgQ;$o z(86-0rFF0uKt{QO>0bg(&fB8!LWprb#zymaHmnQ{6E>5<4($sD>fm$4{{2+no@O4S z0k`}+Xb)_lC5uWv9diowq!Aq8sG(-0D}N33zVc8B&j;O}BglX*DX zSo~H&0eA+R05$D*#@2B~W5Bn$!RzO(=$G%S!J%9O6tkk4)U!4Q;GODXYtTO zC=x+#*61^eqBe$Q>s(#CL@>gFFL+-!pPUI9IzN9?6$;pJ{`yP15^;}tdPD7V6%~Md zYbb$p%wYTJqw#10$tW;-(e3#vA#msmnMBt#w6>lSw0&>zOPV*sQK77Gh0{~-OI-Qa#XFe%Z16(T(DJi!S zJ-DcjYt3)ptq$Q%nM(_pb4`;9E4Zh3%Sp0F3{z+;zWH`x`DHOBdSBDKL{Grbxbenu zgZSBhv$y`_+Nu0T<2c!}b%j%crM5m8`(N`0)Yt^5fYT-gVS%{J0+?f!_^i%$DpctZNKN-CX37xE-gshS%9 zNBZ=^U;&rLqpgyxoLql{<%9(fGb9Ov!O6ZVtES9mer62`uDzHG0AX?{{fqdKpI?Q7 z)w5V_=F?|)wwj3H^Ju6MF;Geu(B>kcfv8Fe!p|JxpfxVv#7;UmK7*6`MoKwD-sWwy z6ZY)s3%m4X0t_?;tE{+R1eYd3k}h;9p~4u%}DdsdBrz zcHaX<*_tbC@n&j~X^gUDy;&`N1ute|FgASe{}gxS@lbBzzf!ll-BMY)S&Jw)l43Nr z2+2+=>*$s%G=_|f>`K{}5XBhVSfY?^24lHV_Q5cSv6S6RW5P7q{m!eqbbp`E@9*FI zHSc-f=e*~A&iXv(Jm0Uv&l#FZ;^;t;s@I`EY3ARmw~v3bY_a+oV~#lXepsUI`9w;g zQVdb{Ov91o(Uy`lp#ZKq!{ktDguu_TypJ|2&mB_Mn_C&F(mXIQuJ7^av)i}QaOKp9 z2ai;LvotC^mM)iMz}Xj6DQ4c$@M=$_=*3z@{6150fQz)XB-n~Q1KU7*E5_}sUE}Ot zIq$vqt|##)S7O*U#mlJrMn$mm0yd4dLB2C+Os+eg?tk-AokmOWcNn05Za`0|n?a85 z@SjDukWhYj0VMhS&_}t{Gny?&|5uKG30@c*;N?^Mm#O|==`+w_7afAQJ5qx@jdJ97chX*7cg&+({aSb5tZh!KGgG{EVAu=kmqI_#V8hlDdfJwv((3Zgk~pageEo76=b9V)jy4< z;v>>A=Z2k@&YLP)%!S4H+s%5tPl64ZlBQ;aVmW=VqGhXkharu?rUz9)B_Siv6m7>jh3SMV&8KCg5Eq4Z721oVpS0^hwV2{FIyHB+jtDYc^kBxol zuiN00l9EC*yAUMIt+97u5H~%u5FoPsq^GYx&!M^E&2o(})6^lSa54c!`?Am`tH1jM z2rcVWTa|XH_!NxEa|3|nYirXNiPjg(v$A%68x5#K)M^I*65Ibl_&(ZUd0}$tO9OXy z5Cl&?+mky!;=@YtBz5Nigmn=R&R6%lynu$UOZEI^%K*nDoQyT$BP(E&glhyeQ@;YZ z{69R~lZ01deE`>KvHP@<7rZwc;wuL~^ybCQWp2Q~U{+bs&j8cY8W%v;@A$)ytgy;q zHbltQ?pgViEf0``>Ga2trIO>JOIv}}RNofF#Y`C+! z;lx#~@DyP*uTVDNtTnzI)hs6w!T@m87R9%pRKKTG<}9o=h;9TLt1a&o4Oo-g0M*#q z_*4Xq>H&0^C{GRUQxo^A&MPzpvyc50f6_P+7Ac^hr}QZb|9b(&qc{KhQg4yJ2U!Nt zO~*Ag&s$X7%UD}&G4@B3JvxNaMIU>P`k5=SPq+fK_y^NCPm^ocP7G9a=WMRlZ8rS* zkSn`Khc-cV8LdU+L!5Z`nSxpV`KT@$8;?7`kK=u>N&vEJF56#LcxG`iasSfRwnJmH@Nt&Di|} zkYihTPC6j#kQhb9Qq8Z+AR?zt!NE9HCCqKSaUj7Ajb2dbhr9o2s(Pa#XX-whE$rwU zBVHqfL#A*u-LalBd@hTi-`JdnI#1U6DwQYHe|om^)?{l!1(QHac4q0u;W1>O&oXu* ztVn8j`Nb-9?7@FZSTZ(KlP!syXpZflQ9ne6I1$EqDH);HKovd((Wb?AO}EDzqhwM^ zl4fp!nOR^B*EM^8W|*YtQZ*}?qU>4tsT=UE=<0-~7$U9e{A(gZt-kdxo!A|msn$mo z!fJ*bXerF#ofi`n@nf4-)_JmQ83i)_gC*I!ebF;umVb+!6AuX%;k1}WL`5Z}@%FmI z{6G}xxl0E9W<;?SO66jQvPP`VU=DlOb2Os{X8Olsz{YgIALb(TGsC&YqDS{n`BM7SVWTP&F^A`LI>7JM zXb+Xu{){5UE5$h=c|3Tso4;^zs{{f!DVyG_KcY8WCsp1rNn250HpLxN7OYFauvN2G zt@NT87Z98E`(&G+?<9PS!~4y4OUybpy?X~SCYGc$V;tfO45R68J}C4J(W(xLXJ7}7 z{`m@^3O|+B7zPG5!d-$F!DGnO%N^Tak$8!K>%*kbR7M>a+wYY64*0GziESe~Y+voV zhwLGpmeIj#BvMs$ekWuAUXrTN-5p+H`n)+u>?j`}-<#+LF^5MYY6W2gsjHV;C~(GC zvS0TFWAqhgQeIq8Z>fW^iG0Li)tx<@844cT)+o{BB%RLu&^`6R?1`c@gtqQFGS5^%>GdVj7zw7+x4RzSyP7t)MkfSXmLq^#}KWc34Uc6ob6q zJodbCSV}2pQ0wCD6A}Isp&;mL5gR;LC|~%vv2y>fXVqKr&wpWmG~xipLOyE3Kt8@Y z{RyZHI*nN5>!uMc>d~Jw_Xe;wq_sa3Q9_ZPSTQbW*QDqYV5UdSzPSdy4Fm(}%|V?5 z=RM%LR9mbwgR3~5_?{|*OTo~nsVsrXo{H#zuf66aircmCp?He%avDXoEBO;}Kr`<| zWGcv@XoC|kMTq@5iR?G3tQlqX{(jcEF#cD+Qux&f;38rIi&jd zs#Z&~BWl6xBJhJ`c&jNWqD4dfMIzz zSrMQPmgY=-=+bm>bbR^s+_EkV#H0@hyO-J7>-T>^qv)xC*89_JZdxKmAiREK);J*U z;xR)6ZRuBdzM(`o`s%k~r=FaaQyf5sO|$1&uUKboZm<+G9d8SvF|*n`JZM=;niR6N zOQrVZE-5{O@iTdXo#HVnX!5$Duw$zvz14}y(Th(o$vh&i>dkg+u5TR}K;LbZ4Bufw z1)O^}wa)3!cT7YQwt7K_Er_EQ3P4(q3j1*jMmpbWAVl+=%;&n624M10Vi@+0hZYX@ z_AQ0;Y`+saG^L-YoRu5`3YEEN*lXuK+dIg?OIf1eeM`#fUKSphcY~D5DfUMgONa2T zc?IDdZEoiAL?juf3%UkprE!vsN|h0|$AXT5TAU%iuzh;fN1v&z>O<+`4L~jy7JT)6 z#{-=J+?)MTL#YcZ2e8#(0#|7AmJxV&a*{d%BNeAPtm-r*j8eo*G|Ocad-Fo2t|p7jJq3vb${Td9S9q!psxW}&>(UFLio+v*2U zCE{{&rcfu;DP=ne&mCyfQe-i(5hPk5Kq zD4bDM$U>Ieqlsr-nsV?{sd3HQvtFKri#}_fJ&_wc!cRJ9dc@AVE#S+?x53V{8n_fu zZ?l0!t#~EMW21>H7C58Ure2uov*aq*tCl@6xL)0yz1UOrPRty`k~|+5>j6q+`Gm8T znYVYpU8bejs96i)+OnK|ks()wql+PohwH7eR{2dpe@BOtR}aY7 z_Q%?SZ|n%+RFaY5t>sNt`KS9wC=0Putw5bkpDW0VQLvah(nMyIRzuc|z3Bd2#}uJ* zMoZ%o$Dg*kbK7vDP`G&?+${)cgZ79YX`KLVqgO$s5z1FgWVOstWeU8f7_RA znvjA~nl{K36}CzZKAbQN<~pgiI3a(5Bf0?-24I$=d#@}{r|E~pWqy)xjQ9U|DqnB- zcijUX%&d9RsQ+p~ib0qVCV4h7h1yqb@uobiDm2azu%{*3YalQ!@XVF~#~sooNn%sf z{m<{zW@kI5*n=q%{z@lWDE7dySwon~2vvKC4`#{WBG2g~tO^3;`9p+kN+RO$tcPxxu%21|voHIyGS<8u5UOCY9 z^#;y~2C1G>gED+3OY~wQ7o8au_=PDLYtX6{mC7pjk|(|e6pZS!e0egtsnXQM9+tSo zzukYQ_oKtFgI4#-&$X_A6|=RGqvrX}I4%v-r#Ckio?n$q4oj32%9xnh(!FW_rS7-% zk5;8_eQs}TS)WgmgRcx*6krBM9NL1#qUGlgMiH~zF7ak$CT%M)Ri&*a(+KvoA%*)X zi7LmNda5>@tgHmUx^sGlpX4s;$BzBXZ@_KYH|aW~6T0zw7Enkf@~oFNNrs>8Zm*vB zV#@opF{XT*5zy|Fd+rHhHy5`>tsCYOC= zTc_%`l=dJ=5wWHyvDeRmc zRIxLss!2&{+VV!lWkI@_9^$gpST?34x(MZTHJU^JWQ0A{trx#wLhR*8(m4jp3cXQ@ zjlq-`HuT>n!nI6Y!pmS^Gv6k_;N88rQH5mnFnYyl+a+LK%$2nqqBTxKhM>*3ukWo< z95V=CHKvycZX__dh+c)ScX7Oy?_zb%v&^hrR>g)#(Dt2>J!oU*H7_Um5rT2YWxVVE z*J%F7R#wOE{qk!k3_mWo<)Z#4eamqF6T-Gu(hMuw+T8lD^nbQK|8)R-x4-WN11DRD z$r$o~-++$TkRdO?d8OLeAAJmv3joNbK&LFuKU)&`uN}YTVsJbU`ELMH^WUV=KRO;9 zpc(HMiCQQ|=||azn{_p$y_Dj8Sa**iw{%fun#&^p)49`EEtmkx0NW z{T>+X0Um=s;0?#r(;sZNMn!D$Y*P>1wtWY;h)QU5bo2v2>^D>waPbVHidS4*+zqf? zUOAmqCpbJjO!@F(i4+4jhMwLT&i7`_(wV_$1YPMK+to%Rx;ABKhCr0Ma(*jpi>muh zLKp5GwF{Wf7An3=XLAga4i^*@6gv-; zK<<^H3ODhaL==qx?9^S(kUox?lm+s2X3~ltKv%yC2}N>?s=Zs7Y(t(+l(vkE=~)JY zZ6hGk#b;z32TF(!nu-O#8otVLvZ?ij7v8K(4RZ8v2>7mV_3dv<|I9g^ z1nF;sXNJYhcTWIxj)kA6-v;d-Cu0=>Us>%1 zw=u0UB5~SBy}#(D=y-qDnv?u5jMdJGvN zvbNQsQ&Uq*Ys>B`J{;*$+A@(TvlEB>-!R4d7uiO-!a=# z=JbAX+DC(@9nc^z^0+p|s`;S-KZh==NE53kIz2mHhS?;)A31gO_|Z~yk- zhO6^WTLu3s{r`CIZK=22`K|T^G-PqnAifvL8_|dYa_$c%Rf9nDC$B&lxSNXn=2H)>Ir0?3< yNsl7`^APy+FcYNx-EaREzb1R^|4W4*Zwef}eKtyB{FiOur>kwGRe0(5NB;w~1Qt*L literal 0 HcmV?d00001 diff --git a/source/images/blog/2021-04/automation-tracing.png b/source/images/blog/2021-04/automation-tracing.png new file mode 100644 index 0000000000000000000000000000000000000000..7c7aa1fa35c53dfa9f15d68f34afe5f33381f13c GIT binary patch literal 78974 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

    @Qh>5bH^E-38+6#&dE8y&ire2vGT`1DA;d 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 z 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 d|GTdovYJFE^FNEwf)IiK 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 N=i;(r`67DW{|~e1vP%E} literal 0 HcmV?d00001 diff --git a/source/images/blog/2021-04/filters.png b/source/images/blog/2021-04/filters.png new file mode 100644 index 0000000000000000000000000000000000000000..a668f53068ec85a7358f7d4468b05302c0324a5f GIT binary patch literal 67999 zcmdqIWk4Ov5-y4+NN|F?2X}XO3lf3_cXx;2?iSo3xCeK4cMBfe9o~?Aww!(L`*(lc zFl04rrmecFyXyODg5_n!;9#&|KtMp?B*cXkK|sJ`K|ny8q22)B2!)&pfq=lwnFtBV zO9%-O$lF>OnwT4afQSdjC%#pRT|o9ec`0C%1Vf5Kc16iW;g^J>@&0O$7#{_JEExn1 z+8se%_C-VlV*0%%ghEA$_dFsj8d^_)hc7kdFG@7?!b1e^&g0gLRW7U1NQ)!QD?C zF+CwUnPsqz*xaXE3M4ZM$&l=Y)acjRIXTsZT|<#1-iev?sV7k~iEq>C3-`Adnq