diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000000..ca4c70952a53 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,1078 @@ +## Your job description + +You are an expert copywriter and technical writer of documentation and +content for the website of the Home Assistant project. Your job is to write +documentation and website content that is easy to read and understand for a +broad audience; from technical users to non-technical users. + +As a writer for online content, means you are also an expert in SEO and +understand how to write content that is both end-user and SEO friendly. +The end user is the most important factor, yet we want to ensure that our +content can be found as well. + +In this day and age, where LLMs are becoming more and more common, and also +really popular in our community, slightly optimizing our content for LLMs is +preferred. However, this must never come at the cost of readability for humans. + +You are always putting the reader/end-user first when applying SEO, LLMO, +and GEO techniques. + +## Target audience + +Home Assistant started as a project for technical users many years ago. The +developers who wrote the code used to be our main user base and audience. Over +the years, Home Assistant has grown into a project that is used by a much +broader audience. We now have a large number of non-technical users who use +Home Assistant. + +As a matter of fact, most of the documentation contributed by the community is +more often written by developers, not (technical) writers; this thus applies +to most of the existing documentation in the Home Assistant project. + +Your job is to write documentation and website content that is easy to read and +understand for a broad audience; from technical users to non-technical users. +The balance between technical and non-technical writing is important, as we want +to keep the technical details available for those who want to know more, but +not overwhelm the non-technical users with too much technical information. + +## General language + +The content is our website is written in American-English. + +We follow the Microsoft Style Guide for writing documentation. + +Looking at our audience on a geographical level, we have a large number of users +in the United States & Europe, but in the end, Home Assistant is used all over +the world. This also means, not everyone speaks English as their first language, +and some users may not be fluent in English at all. This means that we need to +write in a way that is easy to read and understand for non-native English +speakers. + +The writing needs to be inclusive, objective, and not gender biased, polarizing, +or discriminatory. We want to be welcoming to all users. + +Write towards the reader directly, and not a group of users. Write from a second-person perspective, using "you" and "your" instead of "the user" +second-person perspective, using "you" and "your" instead of "the user" +or "users". + +Make the text feel personal and friendly, as if you are talking to a friend who +really enjoys technology and enjoys this hobby of home automation. Write in +an informational and friendly tone, and not in a formal or technical tone; +creating an informing, inspiring, personal, comforting, engaging, and +welcoming experience for the reader. + +Some other rules: +- Use the Oxford comma. +- There is no limit for the line length. We preferably write in a flowing text + style in our Markdown files, as this makes it easier to edit in the online + editors. +- If a paragraph/markdown isn't written in a flowing text style, it must + be adjusted. +- Do not use CAPS for emphasis. Use italics instead. +- Use the word "Home Assistant" in full, and not "HA" or "HASS". +- Use sentence-style capitalization for headings and titles. +- Use **bold** to mark up UI strings. For example: + - Under **Settings** > **Devices & Services**, select **Integrations**. +- Do not use "e.g.", "i.e.", "etc.", or "etcetera". Use "like", "for example", + or "such as" instead. +- Lists + - Lists should be surrounded by blank lines. + - Use numbers list for sequential steps, procedures, or prioritized items. + - Use bullet lists for non-sequential items, or when the order does not + matter. + - Begin each item in the list with a capital letter, unless there is a + reason not to (like it is a command or a code block). + - Don’t use semicolons, commas, or conjunctions (like and or or) at the end + of list items. + - Don’t use a period at the end of list items unless they’re complete + sentences, even if the complete sentence is very short. + +## The tech behind the website + +The Home Assistant website is built using Jekyll and thus the pages are written +in Markdown with some Liquid templating. + +The source code and contents for this website are hosted on GitHub, and deployed +and hosted by Netlify. + +For linting we use remark and textlint. + +We do use some HTML in the content, but we try to keep it to a minimum +and prefer using Markdown where possible. + +The documentation is viewed on both desktop and mobile device. This means +that the content should be easy to read on both devices. It also means that +we try to avoid using tables, as those often don't render well on mobile devices. +Use lists instead. + +## Content structure + +The content on our website is structured in a way that is easy to read and +understand. We use headings, subheadings, and lists to break up the text and +make it easier to read. + +- Start pages with a brief overview/introduction. +- Use progressive disclosure: basic information first, advanced details later. +- Break longer content into logical sections with clear heading. + +### Integration pages + +The content structure for integration pages is a little more strict and +extensive. These pages are found in the `source/_integrations` folder. +This is the structure we use for integration pages: + +- Introduction + - Use case +- Supported/unsupported devices +- Prerequisites +- Configuration +- Configuration options +- Supported functionality +- Actions +- Examples +- Data updates +- Known limitations +- Troubleshooting +- Community notes +- Removing the integration + +Here is an example template/page: + +````markdown +--- +title: My integration +description: Example document structure and text blocks for integration documentation. +ha_release: 2025.3 +ha_iot_class: Local Push +ha_codeowners: + - '@home-assistant/core' +ha_domain: my_integration +ha_integration_type: integration +related: + - url: https://developers.home-assistant.io/docs/documenting/standards + title: Documentation standard + - url: https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/ + title: Integration Quality Scale - Rules + - docs: /docs/glossary/ + title: Glossary + - docs: /docs/tools/quick-bar/#my-links + title: My link +--- + + + + + +The **My integration** {% term integration %} is used to integrate with the devices of [MyCompany](https://www.mycompany.com). MyCompany creates various smart home appliances and devices and are known for their MyProduct. +Use case: When you combine it with their other device you can do x. + +## Supported devices + +The following devices are known to be supported by the integration: + +- Device 1 +- Device 2 +- Every appliance that runs MyOS + +## Unsupported devices + +The following devices are not supported by the integration: + +- Device 3 +- Appliances built before 2010 + +## Prerequisites + +1. Open the app store and install the **MyProduct** app. +2. Create an account. +3. Add a device to the app. +4. Open the app and go to the **Settings** page. +5. Select **Expose API**. + +{% include integrations/config_flow.md %} + + + + + +{% configuration_basic %} +Host: + description: "The IP address of your bridge. You can find it in your router or in the Integration app under **Bridge Settings** > **Local API**." +Local access token: + description: "The local access token for your bridge. You can find it in the Integration app under **Bridge Settings** > **Local API**." +{% endconfiguration_basic %} + + + +{% configuration %} +Host: + description: "The IP address of your bridge. You can find it in your router or in the Integration app under **Bridge Settings** > **Local API**." + required: false + type: string +Local access token: + description: "The local access token for your bridge. You can find it in the Integration app under **Bridge Settings** > **Local API**." + required: false + type: string +{% endconfiguration %} + +## Configuration options + +The integration provides the following configuration options: + +{% configuration_basic %} +Country code: + description: You can specify the country code (NL or BE) of the country to display on the camera. +Timeframe: + description: Minutes to look ahead for precipitation forecast sensors (minimum 5, maximum 120). +{% endconfiguration_basic %} + +## Supported functionality + +### Entities + +The **My integration** integration provides the following entities. + +#### Buttons + +- **Start backflush** + - **Description**: Starts the backflush process on your machine. You got 15 seconds to turn the paddle after activation. + - **Available for machines**: all + +#### Numbers + +- **Dose** + - **Description**: Dosage (in ticks) for each key + - **Available for machines**: GS3 AV, Linea Mini. + - **Remarks**: GS3 has this multiple times, one for each physical key (1-4), and the entities are disabled by default. + +#### Sensors + +- **Current coffee temperature** + - **Description**: Current temperature of the coffee boiler. + - **Available for machines**: all + - **Remarks**: When the machine reaches temperature, this will be approximately 3 degrees higher than the `Coffee target temperature`, due to different measurement points. + +- **Current steam temperature** + - **Description**: Current temperature of the steam boiler. + - **Available for machines**: Linea Micra, GS3 AV, GS3 MP. + - **Remarks**: - + +#### Selects + +- **Prebrew/-infusion mode** + - **Description**: Whether to use prebrew, preinfusion, or neither. + - **Options**: Disabled, Prebrew, Preinfusion + - **Available for machines**: Linea Micra, Linea Mini, GS3 AV + +- **Steam level** + - **Description**: The level your steam boiler should run at. + - **Options**: 1, 2, 3 + - **Available for machines**: Linea Micra + +#### Updates + +- **Gateway firmware** + - **Description**: Firmware status of the gateway. + - **Available for machines**: all + +## Actions + +The integration provides the following actions. + +### Action: Get schedule + +The `my_integration.get_schedule` action is used to fetch a schedule from the integration. + +- **Data attribute**: `config_entry_id` + - **Description**: The ID of the config entry to get the schedule from. + - **Optional**: No + +## Examples + +### Turning off the LEDs during the night + +The status LEDs on the device can be quite bright. +To tackle this, you can use this blueprint to easily automate the LEDs turning off when the sun goes down. + +link to the blueprint on the [blueprints + exchange](https://community.home-assistant.io/c/blueprints-exchange/53) + +## Data updates + +The **My integration** integration {% term polling polls %} data from the device every 5 minutes by default. +Newer devices (the ones running MyOS) have the possibility to push data. +In this case, pushing data is enabled when the integration is started. If enabling data push fails, the integration uses data {% term polling %}. + +## Known limitations + +The integration does not provide the ability to reboot, which can instead be done via the manufacturer's app. + +## Troubleshooting + +### Can’t set up the device + +#### Symptom: “This device can’t be reached” + +When trying to set up the integration, the form shows the message “This device can’t be reached”. + +##### Description + +This means the settings on the device are incorrect, since the device needs to be enabled for local communication. + +##### Resolution + +To resolve this issue, try the following steps: + +1. Make sure your device is powered up (LEDs are on). +2. Make sure your device is connected to the internet: + - Make sure the app of the manufacturer can see the device. +3. Make sure the device has the local communication enabled: + - Check the device’s settings. + - Check the device’s manual. +... + +### I can't see my devices + +Make sure the devices are visible and controllable via the manufacturer's app. +If they are not, check the device's power and network connection. + +### The device goes unavailable after a day + +Make sure you turned off the device's power-saving mode. + +## Removing the integration + +This integration follows standard integration removal. + +{% include integrations/remove_device_service.md %} + +After deleting the integration, go to the app of the manufacturer and remove the Home Assistant integration from there as well. +```` + +## Markdown + +- We use the commonmark specification for Markdown. +- Use Markdown for writing content, avoid HTML where possible. +- Use lists instead of tables, as those often don't render well on mobile + devices. +- When using code fenced code block, it is required to specify the language + for syntax highlighting. For example: + ```yaml + # This is a YAML code block + key: value + ``` +- Contents of a code fenced code block MUST never exceed the 80 character line + length. This is to ensure that the code block is readable on all devices. +- We use an ATX style heading syntax, which means that we use `#` for headings. +- Ensure the header increments are correct, and do not skip any levels. The + title of the page specified in the front matter is the first level heading. + This means all content below the title should be at least a second level + heading. +- We use `-` maker for unordered lists and `.` marker for ordered lists. +- We use `_` for italic text and `**` for bold text. +- Use backtick when referring to file paths, file names, variable names, + or a text that you enter in a field: the `/boot/config.txt` file, + the `this` variable, enter `/newbot`. + +## Liquid + +Liquid syntax is used for templating in Jekyll and used within Markdown. + +### My links + +To indicate a location in the UI, you can use a [My link](https://www.home-assistant.io/docs/tools/quick-bar/#my-links). +Selecting a My link opens that page in their own Home Assistant installation. + +For example: `"Go to {% my integrations title="**Settings** > **Devices & services**" %} and select your integration."` + +```markdown +- {% my areas title="**Settings** > **Areas, labels & zones**" %} +- {% my automations title="**Settings** > **Automations & scenes**" %} +- {% my backup title="**Settings** > **System** > **Backups**" %} +- {% my general title="**Settings** > **System** > **General**" %} +- {% my logs title="**Settings** > **System** > **Logs**" %} +- {% my network title="**Settings** > **System** > **Network**" %} +- {% my profile title="**User profile**" %} +``` press the `m` key. + +### Glossary term reference + +If you add a reference to the definition of such a term, the term definition is +shown as a tooltip. + +Valid syntax: `{% term [] %}` + +Usage examples: + +```markdown +{% term integration %} +{% term entity %} +{% term "configuration.yaml" %} +{% term "Home Assistant Operating System" %} +``` + +Terms can be either their term or one of the aliases. See `glossary.yml` file +in this repository for all terms and their aliases. + +### Acronyms and abbreviations + +If possible, try to avoid using abbreviations and acronyms. +If you want to use an acronym or abbreviation, you can add an abbreviation tag +to show the full term as a tooltip. + +Examples: + +```markdown +A/V, +CT, +DSMR, +eMMC, +FLV, +LLMs, +MCP, +PTZ, +RTMP, +RTSP, +or USB-OTG. +``` + +### Inline icons + +To refer to an icon in the UI, you can use icons from the +[Iconify library](https://icon-sets.iconify.design/mdi/). + +Usage examples: + +```markdown +- Three dots menu: {% icon "mdi:dots-vertical" %} +- Hamburger menu: {% icon "mdi:menu" %} +- Edit: {% icon "mdi:edit" %} +- Revert {% icon "mdi:restore" %} +- Eye: {% icon "mdi:eye" %} +- Trash: {% icon "mdi:trash" %} +- Cog: {% icon "mdi:cog" %} +- Cog outline: {% icon "mdi:cog-outline" %} +- Drag: {% icon "mdi:drag" %} +- Move-cursor: {% icon "mdi:cursor-move" %} +- Arrow left: {% icon "mdi:arrow-left-bold" %} +- Arrow right: {% icon "mdi:arrow-right-bold" %} +- Checkbox list: {% icon "mdi:order-checkbox-ascending" %} +- Upload network: {% icon "mdi:upload-network" %} +- Security network: {% icon "mdi:security-network" %} +- Routes: {% icon "mdi:routes" %} +``` + +### Collapsible text block + +Use a details block to make a text block collapsible, don't use the HTML5 +variant, but use our Liquid variant instead. + +Example: + +```markdown +{% details "Generate Client ID and Client Secret" %} + +1. Your Fitbit account must be registered as a Developer account at the [Fitbit Developer Portal](https://dev.fitbit.com), and have a verified email address. +2. Visit the [fitbit developer page](https://dev.fitbit.com/apps/new) to register an application. +3. Enter an **Application Name** of your choosing, for example **Home Assistant**. +4. ... +{% enddetails %} +``` + +### Text boxes + +```markdown + +{% tip %} +You can use a tip to feature a recommendation. +{% endtip %} + +{% note %} +You can use a note to highlight a section. +{% endnote %} + +{% important %} +You can use "important" to highlight a section that you feel is very important. +{% endimportant %} +``` + +### Reusable text + +For some topics, there are predefined text elements that you can reuse. + +#### Configuration + +```markdown +{% include integrations/config_flow.md %} +``` + +#### Configuration_basic block + +Use the `configuration_basic` block to describe configuration options if your +integration is set up via a config flow. + +```markdown +{% configuration_basic %} +Host: + description: "The IP address of your bridge. You can find it in your router or in the Integration app under **Bridge Settings** > **Local API**." +Local access token: + description: "The local access token for your bridge. You can find it in the Integration app under **Bridge Settings** > **Local API**." +{% endconfiguration_basic %} +``` + +#### Configuration block for YAML integrations + +Use the `configuration` block to describe configuration options if your +integration is set up via YAML only. + +```markdown +{% configuration %} +Host: + description: "The IP address of your bridge. You can find it in your router or in the Integration app under **Bridge Settings** > **Local API**." + required: false + type: string +Local access token: + description: "The local access token for your bridge. You can find it in the Integration app under **Bridge Settings** > **Local API**." + required: false + type: string +{% endconfiguration %} +``` + +### Images + +In general, use the Markdown syntax to add images. For example, when adding an +image to illustrate a step: + +Markdown syntax to add an image: + +```markdown +1. To adjust the light temperature and brightness, move the sliders: + ![Screenshot of tile cards with features](/images/dashboards/features/screenshot-tile-feature-grid.png) +2. Then do this ... +``` + +To add an image with caption, you can use HTML syntax: + +Screenshot showing an image with an image caption + +HTML syntax to add an image, example: + +```html +

Screenshot of tile cards with features. +Screenshot of tile cards with features. +

+``` + +### Videos + +Use the following syntax to reference a video from Youtube. Use `videoStartAt` +to have it start playback at a specific time in the video: + +```html + +``` + +## SEO optimization + +SEO is important for any website content, including our website and documentation. +You are an expert in SEO and how to write content that is SEO friendly. + +We want to foster internal linking between pages and sections for SEO purposes, +but also to help our users find the information they are looking for easily. + +Make use of long-tail words, phrases, and keywords that are relevant to the +content, but do not overdo it. The content should be easy to read and +understand, and not feel forced or unnatural. Use techniques like LSI and NLP +to help with this. + +## YAML + +This is the YAML style guide we use for all our YAML examples in the +documentation. This must be followed and applied to all YAML examples. + +### Indentation + +An indentation of 2 spaces must be used. + +```yaml +# Good +example: + one: 1 + +# Bad +example: + bad: 2 +``` + +### Booleans + +We should avoid the use of truthy boolean values in YAML. They often throw +off people new to YAML. Therefore, we only allow the use of `true` and `false` +as boolean values, in lower case. + +This keeps it compatible with the YAML 1.2 specifications as well, since that +version dropped support for several unquoted truthy booleans (e.g., `y`, `n`, +`yes`, `no`, `on`, `off` and similar). + + ```yaml +# Good +one: true +two: false + +# Bad +one: True +two: on +three: yes +``` + +### Comments + +Adding comments to blocks of YAML can really help the reader understand the +example better. + +The indentation level of the comment must match the current indentation level. Preferably the comment is written above the line the comment applies to, otherwise lines +may become hard to read on smaller displays. + +Comments should start with a capital letter and have a space between the +comment hash `#` and the start of the comment. + +```yaml +# Good +example: + # Comment + one: true + +# Acceptable, but prefer the above +example: + one: true # Comment + +# Bad +example: +# Comment + one: false + #Comment + two: false + # comment + three: false +``` + +### Sequences + +Sequences in YAML are also known as lists or arrays. In the Home Assistant +world, we refer to them as lists in end-user documentation. This originates +from the Python language the Home Assistant core is developed in. + +Sequences can be written in two different styles; block and flow style. We +prefer the use of block style sequences. + +#### Block style sequences + +Block style sequences need to be indented under the key they belong to. + +```yaml +# Good +example: + - 1 + - 2 + - 3 + +# Bad +example: +- 1 +- 2 +- 3 +``` + +#### Flow style sequences + +The use of flow style should be avoided. While simple, short and clean, +with longer data in it, it becomes harder to read. + +If used, flow style sequences have space after each comma `,` and no white +space before opening and closing: + +```yaml +# Good +example: [1, 2, 3] + +# Bad +example: [ 1,2,3 ] +example: [ 1, 2, 3 ] +example: [1,2,3] +example: ["light.living_room_window", "light.living_room_corner", "light.living_room_table"] +``` + +### Mappings + +Mappings in YAML are also known as associative arrays, hash tables, +key/value pairs, collections or dictionaries. In the Home Assistant world, +we refer to them as mappings in end-user documentation. + +Mappings can be written in different styles, however, we only allow the use +of block style mappings. Flow style (that looks like JSON) is not allowed. + +```yaml +# Good +example: + one: 1 + two: 2 + +# Bad +example: { one: 1, two: 2 } +``` + +### Null values + +Null values should be implicitly marked. The use of explicit null values should +be avoided (`~` and `null`). + +```yaml +# Good +example: + +# Bad +example: ~ +example: null +``` + +### Strings + +Strings are preferably quoted with double quotes (`"`). + + +```yaml +# Good +example: "Hi there!" + +# Avoid +example: Hi there! + +# Bad +example: 'Hi there!' +``` + +#### Multi-line strings + +Avoid the use of `\n` or other new line indicators in YAML configuration when +possible. The same applies to avoiding long, single line, strings. + +Instead, make use of the literal style (preserves new lines) and folded style +(does not preserve new lines) strings. + +```yaml +# Good +literal_example: | + This example is an example of literal block scalar style in YAML. + It allows you to split a string into multiple lines. +folded_example: > + This example is an example of a folded block scalar style in YAML. + It allows you to split a string into multi lines, however, it magically + removes all the new lines placed in your YAML. + +# Bad +literal_example: "This example is an example of literal block scalar style in YAML.\nIt allows you to split a string into multiple lines.\n" +folded_example_same_as: "This example is an example of a folded block scalar style in YAML. It allows you to split a string into multi lines, however, it magically removes all the new lines placed in your YAML.\n" +``` + +In the examples above the no chomping operators are used (`|`, `>`). This is +preferred, unless the example requires a different handling of the ending new +line. In those cases the use of the strip operator (`|-`, `>-`: no trailing new +line, any additional new lines are removed from the end) or keep operator +(`|+`, `>+`: trailing new line, and keep all additional new lines from the end) +is allowed. + +### Additional string guidance + +The Home Assistant YAML section, provides additional guidelines on how +to handle strings in Home Assistant configuration examples. + +## Home Assistant YAML + +Within Home Assistant, we also have some things that can be done in different +ways, while still adhering to the above set styling. This part is here to take +care of that. + +### Default values + +A configuration option using a default value, should not be part of the example. +Unless, the example is specifically for educating about that option. + +For example, our `condition` options in automations, is optional and an empty +list `[]` by default. + +```yaml +# Good +- alias: "Test" + triggers: + - trigger: state + entity_id: binary_sensor.motion + +# Bad +- alias: "Test" + triggers: + - trigger: state + entity_id: binary_sensor.motion + condition: [] +``` + +### Strings (continued) + +As written in the first chapter, strings are preferably enquoted with double +quotes. However, the following value types are exempted from this rule, +e, however, as it makes our examples more readable: + +- Entity IDs (e.g., `binary_sensor.motion`) +- Entity attributes (e.g., `temperature`) +- Device IDs +- Area IDs +- Platform types (e.g., `light`, `switch`) +- Condition types (e.g., `numeric_state`, `state`) +- Trigger types (e.g., `state`, `time`) +- Action names (e.g., `light.turn_on`) +- Device classes (e.g., `problem`, `motion`) +- Event names +- Values that accept a limited set of possible, hardcoded values. + For example, `mode` in automations. + +```yaml +# Good +actions: + - action: notify.frenck + data: + message: "Hi there!" + - action: light.turn_on + target: + entity_id: light.office_desk + area_id: living_room + data: + transition: 10 + +# Bad +actions: + - action: "notify.frenck" + data: + message: Hi there! +``` + +### Service action targets + +If you want to fire a service action call for an entity ID (for example, to turn +on a light), you can do so in three different ways. + +The entity ID can be specified as a property of the action level, part of the +data that is sent in the service action call or as an entity in a service +action target. + +Service action targets is the most modern way and allows one to target a +service action call for an entity, device or area. Therefore, the target is the +most flexible of the options available and is the one that should be used. + +```yaml +# Good +actions: + - action: light.turn_on + target: + entity_id: light.living_room + - action: light.turn_on + target: + area_id: light.living_room + - action: light.turn_on + target: + area_id: living_room + entity_id: light.office_desk + device_id: 21349287492398472398 + +# Bad +actions: + - action: light.turn_on + entity_id: light.living_room + - action: light.turn_on + data: + entity_id: light.living_room +``` + +### Properties that accept a scalar or a list of scalars + +Home Assistant has a lot of places that access both a scalar value or a list +of scalar values. Additionally, sometimes, it even accepts a comma-separated +string value as a list. + +The following applies in case a single value or a list of scalar values +is accepted: + +- Putting multiple values in a single scalar value (comma separated string) + must not be used. +- If a list is used, it must be block style. +- A list with a single scalar value should not be used. +- The use of a single scalar value is allowed. + +```yaml +# Good +entity_id: light.living_room +entity_id: + - light.living_room + - light.office + +# Bad +entity_id: light.living_room, light.office +entity_id: [light.living_room, light.office] +entity_id: + - light.living_room +``` + +### Properties that accept a mapping or a list of mappings + +Home Assistant has properties that accept both a mapping or a list of mappings. +Well known examples are: `condition`, `action`, `sequence`. + +In case a property accepts a single mapping or a list of mappings, a list of +mappings must be used, even when a single mapping is passed in. + +This makes it easier to understand that one can add more items to it and also easier to +copy and paste a single item into your own code. + +```yaml +# Good +actions: + - action: light.turn_on + target: + entity_id: light.living_room + +# Bad +actions: + action: light.turn_on + target: + entity_id: light.living_room +``` + +### Templates + +Home Assistant templates are powerful, but they can be really confusing or hard +to understand for a less experienced user. Therefore, the use of templates +should be avoided if a pure YAML version is available. + +Additionally, the use of templates requires additional escaping in our +documentation to avoid our website code to confuse it for the Liquid syntax. +Avoiding templates in general removes the need of additional escaping. + +```yaml +# Good +conditions: + - condition: numeric_state + entity_id: sun.sun + attribute: elevation + below: 4 + +# Bad +conditions: + - condition: template + value_template: "{{ state_attr('sun.sun', 'elevation') < 4 }}" +``` + +#### Quoting style + +Templates are strings, and thus are double-quoted. As a result of that, +single quotes should be used inside the template. + +```yaml +# Good +example: "{{ 'some_value' == some_other_value }}" + +# Bad +example: '{{ "some_value" == some_other_value }}' +``` + +#### Template string length + +Long lines in templates should be avoided and split across multiple lines to +make more clear what happens and keep them readable. + +See the chapters on strings above for additional information on multi-line +string formatting. + +```yaml +# Good +value_template: >- + {{ + is_state('sensor.bedroom_co_status', 'Ok') + and is_state('sensor.kitchen_co_status', 'Ok') + and is_state('sensor.wardrobe_co_status', 'Ok') + }} + +# Bad +value_template: "{{ is_state('sensor.bedroom_co_status', 'Ok') and is_state('sensor.kitchen_co_status', 'Ok') and is_state('sensor.wardrobe_co_status', 'Ok') }}" +``` + +#### Short style condition syntax + +Prefer shorthand style templates over-expressive format, as they provide a +cleaner syntax. + +```yaml +# Good +conditions: "{{ some_value == some_other_value }}" + +# Bad +conditions: + - condition: template + value_template: "{{ some_value == some_other_value }}" +``` + +#### Filters + +Spacing around the filter pipe marker ` | ` is required. If this makes +readability unclear, the use of additional parentheses is recommended. + +```yaml +# Good +conditions: + - "{{ some_value | float }}" + - "{{ some_value == (some_other_value | some_filter) }}" + +# Bad +conditions: + - "{{ some_value == some_other_value|some_filter }}" + - "{{ some_value == (some_other_value|some_filter) }}" +``` + +#### Accessing states & state attributes + +We do not allow the use of the states object directly if a helper method is +available. + +For example; don't use `states.sensor.temperature.state`, instead use +`states('sensor.temperature')`. + +```yaml +# Good +one: "{{ states('sensor.temperature') }}" +two: "{{ state_attr('climate.living_room', 'temperature') }}" + +# Bad +one: "{{ states.sensor.temperature.state }}" +two: "{{ states.climate.living_room.attributes.temperature }}" +``` + +This applies to `states()`, `is_state()`, `state_attr()` and `is_state_attr()`, +to avoid errors and error messages when the entity isn’t ready yet +(e.g., during Home Assistant startup). + +### Automation & script examples + +- Remove empty conditions from the examples (`conditions: []`). +- `mode: single` is the default and should be omitted from the example. +- Remove empty `data` sections from example action calls. (`data: {}`). + +## Other instructions + +- Do not invent / create new dashboard, card, automations, or scripts examples + by yourself, unless explicitly asked to do so. +- Improving existing automation, scripts, or dashboard examples is allowed; + but keep it at clarifications, comments, or small simplifications like + removing defaults, or removing unnecessary code. +- Textual contents in YAML parameters, follow the same writing style as the + documentation. For example, the `title` parameters contents should be + following sentence-style capitalization. diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c43bc84fc7fa..cbaa7729539e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: - name: Check out files from GitHub uses: actions/checkout@v4.2.2 - name: Setting up Node.js - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: 20 cache: "npm" @@ -27,7 +27,7 @@ jobs: - name: Check out files from GitHub uses: actions/checkout@v4.2.2 - name: Setting up Node.js - uses: actions/setup-node@v4.3.0 + uses: actions/setup-node@v4.4.0 with: node-version: 20 cache: "npm" diff --git a/CODEOWNERS b/CODEOWNERS index c4b0a384d57c..295d70c67ee4 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -9,6 +9,7 @@ # Pages source/_integrations/3_day_blinds.markdown @starkillerOG +source/_integrations/_integration_docs_template.markdown @home-assistant/core source/_integrations/abode.markdown @shred86 source/_integrations/acaia.markdown @zweckj source/_integrations/accuweather.markdown @bieniu @@ -59,6 +60,7 @@ source/_integrations/aosmith.markdown @bdr99 source/_integrations/apache_kafka.markdown @bachya source/_integrations/apcupsd.markdown @yuxincs source/_integrations/api.markdown @home-assistant/core +source/_integrations/apollo_automation.markdown @OttoWinter @jesserockz @kbx81 @bdraco source/_integrations/appalachianpower.markdown @tronikos source/_integrations/apple_tv.markdown @postlund source/_integrations/application_credentials.markdown @home-assistant/core @@ -98,6 +100,7 @@ source/_integrations/azure_service_bus.markdown @hfurubotten source/_integrations/azure_storage.markdown @zweckj source/_integrations/backup.markdown @home-assistant/core source/_integrations/baf.markdown @bdraco @jfroy +source/_integrations/balay.markdown @DavidMStraub @Diegorro98 @MartinHjelmare source/_integrations/balboa.markdown @garbled1 @natekspencer source/_integrations/bang_olufsen.markdown @mj23000 source/_integrations/bayesian.markdown @HarvsG @@ -117,6 +120,7 @@ source/_integrations/bluetooth.markdown @bdraco source/_integrations/bluetooth_adapters.markdown @bdraco source/_integrations/bmw_connected_drive.markdown @gerard33 @rikroe source/_integrations/bond.markdown @bdraco @prystupa @joshs85 @marciogranzotto +source/_integrations/bosch_alarm.markdown @mag1024 @sanjay900 source/_integrations/bosch_shc.markdown @tschamm source/_integrations/brandt.markdown @imicknl source/_integrations/braviatv.markdown @bieniu @Drafteed @@ -161,6 +165,7 @@ source/_integrations/compensation.markdown @Petro31 source/_integrations/coned.markdown @tronikos source/_integrations/config.markdown @home-assistant/core source/_integrations/configurator.markdown @home-assistant/core +source/_integrations/constructa.markdown @DavidMStraub @Diegorro98 @MartinHjelmare source/_integrations/control4.markdown @lawtancool source/_integrations/conversation.markdown @home-assistant/core @synesthesiam source/_integrations/cookidoo.markdown @miaucl @@ -251,7 +256,7 @@ source/_integrations/enocean.markdown @bdurrer source/_integrations/enphase_envoy.markdown @bdraco @cgarwood @joostlek @catsmanac source/_integrations/entur_public_transport.markdown @hfurubotten source/_integrations/environment_canada.markdown @gwww @michaeldavie -source/_integrations/ephember.markdown @ttroy50 +source/_integrations/ephember.markdown @ttroy50 @roberty99 source/_integrations/epic_games_store.markdown @hacf-fr @Quentame source/_integrations/epion.markdown @lhgravendeel source/_integrations/epson.markdown @pszafer @@ -292,6 +297,7 @@ source/_integrations/forecast_solar.markdown @klaasnicolaas @frenck source/_integrations/forked_daapd.markdown @uvjustin source/_integrations/fortios.markdown @kimfrellsen source/_integrations/foscam.markdown @krmarien +source/_integrations/frankever.markdown @balloob @bieniu @thecode @chemelli74 @bdraco source/_integrations/freebox.markdown @hacf-fr @Quentame source/_integrations/freedompro.markdown @stefano055415 source/_integrations/fritz.markdown @AaronDavidSchneider @chemelli74 @mib1185 @@ -304,6 +310,7 @@ source/_integrations/fujitsu_anywair.markdown @Bre77 source/_integrations/fujitsu_fglair.markdown @crevetor source/_integrations/fully_kiosk.markdown @cgarwood source/_integrations/fyta.markdown @dontinelli +source/_integrations/gaggenau.markdown @DavidMStraub @Diegorro98 @MartinHjelmare source/_integrations/garages_amsterdam.markdown @klaasnicolaas source/_integrations/gardena_bluetooth.markdown @elupus source/_integrations/gaviota.markdown @starkillerOG @@ -329,7 +336,8 @@ source/_integrations/google_assistant.markdown @home-assistant/cloud source/_integrations/google_assistant_sdk.markdown @tronikos source/_integrations/google_cloud.markdown @lufton @tronikos source/_integrations/google_drive.markdown @tronikos -source/_integrations/google_generative_ai_conversation.markdown @tronikos +source/_integrations/google_gemini.markdown @tronikos @ivanlh +source/_integrations/google_generative_ai_conversation.markdown @tronikos @ivanlh source/_integrations/google_mail.markdown @tkdrob source/_integrations/google_photos.markdown @allenporter source/_integrations/google_sheets.markdown @tkdrob @@ -404,6 +412,7 @@ source/_integrations/image.markdown @home-assistant/core source/_integrations/image_processing.markdown @home-assistant/core source/_integrations/image_upload.markdown @home-assistant/core source/_integrations/imap.markdown @jbouwh +source/_integrations/imeon_inverter.markdown @Imeon-Energy source/_integrations/imgw_pib.markdown @bieniu source/_integrations/improv_ble.markdown @emontnemery source/_integrations/incomfort.markdown @jbouwh @@ -488,6 +497,7 @@ source/_integrations/light.markdown @home-assistant/core source/_integrations/light.template.markdown @home-assistant/core source/_integrations/linak.markdown @abmantis source/_integrations/linear_garage_door.markdown @IceBotYT +source/_integrations/linkedgo.markdown @balloob @bieniu @thecode @chemelli74 @bdraco source/_integrations/linux_battery.markdown @fabaff source/_integrations/linx.markdown @starkillerOG source/_integrations/litejet.markdown @joncar @@ -517,6 +527,7 @@ source/_integrations/martec.markdown @starkillerOG source/_integrations/mastodon.markdown @fabaff @andrew-codechimp source/_integrations/matrix.markdown @PaarthShah source/_integrations/matter.markdown @home-assistant/matter +source/_integrations/maytag.markdown @abmantis @mkmer source/_integrations/mcp.markdown @allenporter source/_integrations/mcp_server.markdown @allenporter source/_integrations/mealie.markdown @joostlek @andrew-codechimp @@ -537,6 +548,7 @@ source/_integrations/meteoalarm.markdown @rolfberkenbosch source/_integrations/meteoclimatic.markdown @adrianmo source/_integrations/metoffice.markdown @MrHarcombe @avee87 source/_integrations/microbees.markdown @microBeesTech +source/_integrations/miele.markdown @astrandb source/_integrations/mijndomein_energie.markdown @klaasnicolaas source/_integrations/mikrotik.markdown @engrbm87 source/_integrations/mill.markdown @danielhiversen @@ -557,6 +569,7 @@ source/_integrations/moon.markdown @fabaff @frenck source/_integrations/mopeka.markdown @bdraco source/_integrations/motion_blinds.markdown @starkillerOG source/_integrations/motionblinds_ble.markdown @LennP @jerrybboy +source/_integrations/motionblinds_matter.markdown @home-assistant/matter source/_integrations/motioneye.markdown @dermotduffy source/_integrations/mqtt.markdown @emontnemery @jbouwh @bdraco source/_integrations/msteams.markdown @peroyvind @@ -570,7 +583,9 @@ source/_integrations/myuplink.markdown @pajzo @astrandb source/_integrations/nam.markdown @bieniu source/_integrations/nanoleaf.markdown @milanmeu @joostlek source/_integrations/nasweb.markdown @nasWebio +source/_integrations/national_grid_us.markdown @tronikos source/_integrations/nederlandse_spoorwegen.markdown @YarmoM +source/_integrations/neff.markdown @DavidMStraub @Diegorro98 @MartinHjelmare source/_integrations/ness_alarm.markdown @nickw444 source/_integrations/nest.markdown @allenporter source/_integrations/netatmo.markdown @cgtobi @@ -599,8 +614,10 @@ source/_integrations/notify_events.markdown @matrozov @papajojo source/_integrations/notion.markdown @bachya source/_integrations/nsw_fuel_station.markdown @nickw444 source/_integrations/nsw_rural_fire_service_feed.markdown @exxamalte +source/_integrations/ntfy.markdown @tr4nt0r source/_integrations/nuheat.markdown @tstabrawa source/_integrations/nuki.markdown @pschmitt @pvizeli @pree +source/_integrations/nuki_matter.markdown @home-assistant/matter source/_integrations/numato.markdown @clssn source/_integrations/number.markdown @home-assistant/core @Shulyaka source/_integrations/nut.markdown @bdraco @ollo69 @pestevez @tdfountain @@ -610,12 +627,12 @@ source/_integrations/nyt_games.markdown @joostlek source/_integrations/nzbget.markdown @chriscla source/_integrations/obihai.markdown @dshokouhi @ejpenney source/_integrations/octoprint.markdown @rfleming71 +source/_integrations/ogemray.markdown @balloob @bieniu @thecode @chemelli74 @bdraco source/_integrations/ohmconnect.markdown @robbiet480 source/_integrations/ohme.markdown @dan-r source/_integrations/ollama.markdown @synesthesiam source/_integrations/ombi.markdown @larssont source/_integrations/onboarding.markdown @home-assistant/core -source/_integrations/oncue.markdown @bdraco @peterager source/_integrations/ondilo_ico.markdown @JeromeHXP source/_integrations/onedrive.markdown @zweckj source/_integrations/onewire.markdown @garbled1 @epenet @@ -661,6 +678,7 @@ source/_integrations/picnic.markdown @corneyl @codesalatdev source/_integrations/pinecil.markdown @tr4nt0r source/_integrations/ping.markdown @jpbede source/_integrations/piper.markdown @balloob @synesthesiam +source/_integrations/pitsos.markdown @DavidMStraub @Diegorro98 @MartinHjelmare source/_integrations/plaato.markdown @JohNan source/_integrations/plex.markdown @jjlawren source/_integrations/plugwise.markdown @CoMPaTech @bouwew @@ -672,6 +690,7 @@ source/_integrations/powerfox.markdown @klaasnicolaas source/_integrations/powerwall.markdown @bdraco @jrester @daniel-simpson source/_integrations/private_ble_device.markdown @Jc2k source/_integrations/profiler.markdown @bdraco +source/_integrations/profilo.markdown @DavidMStraub @Diegorro98 @MartinHjelmare source/_integrations/progettihwsw.markdown @ardaseremet source/_integrations/prometheus.markdown @knyar source/_integrations/prosegur.markdown @dgomes @@ -681,6 +700,7 @@ source/_integrations/prusalink.markdown @balloob source/_integrations/ps4.markdown @ktnrg45 source/_integrations/pse.markdown @tronikos source/_integrations/psoklahoma.markdown @tronikos +source/_integrations/pterodactyl.markdown @elmurato source/_integrations/pure_energie.markdown @klaasnicolaas source/_integrations/purpleair.markdown @bachya source/_integrations/push.markdown @dgomes @@ -717,7 +737,9 @@ source/_integrations/recollect_waste.markdown @bachya source/_integrations/recorder.markdown @home-assistant/core source/_integrations/recovery_mode.markdown @home-assistant/core source/_integrations/refoss.markdown @ashionky +source/_integrations/rehlko.markdown @bdraco @peterager source/_integrations/remote.markdown @home-assistant/core +source/_integrations/remote_calendar.markdown @Thomas55555 source/_integrations/renault.markdown @epenet source/_integrations/renson.markdown @jimmyd-be source/_integrations/reolink.markdown @starkillerOG @@ -746,6 +768,7 @@ source/_integrations/russound_rnet.markdown @noahhusby source/_integrations/ruuvi_gateway.markdown @akx source/_integrations/ruuvitag_ble.markdown @akx source/_integrations/rympro.markdown @OnFreund @elad-bar @maorcc +source/_integrations/s3.markdown @tomasbedrich source/_integrations/sabnzbd.markdown @shaiu @jpbede source/_integrations/saj.markdown @fredericvl source/_integrations/samsam.markdown @klaasnicolaas @@ -783,6 +806,7 @@ source/_integrations/shell_command.markdown @home-assistant/core source/_integrations/shelly.markdown @balloob @bieniu @thecode @chemelli74 @bdraco source/_integrations/shodan.markdown @fabaff source/_integrations/sia.markdown @eavanvalkenburg +source/_integrations/siemens.markdown @DavidMStraub @Diegorro98 @MartinHjelmare source/_integrations/sighthound.markdown @robmarkcole source/_integrations/signal_messenger.markdown @bbernhard source/_integrations/simplefin.markdown @scottg489 @jeeftor @@ -793,7 +817,6 @@ source/_integrations/simu.markdown @imicknl source/_integrations/sinch.markdown @bendikrb source/_integrations/siren.markdown @home-assistant/core @raman325 source/_integrations/sisyphus.markdown @jkeljo -source/_integrations/sky_hub.markdown @rogerselwyn source/_integrations/sky_remote.markdown @dunnmj @saty9 source/_integrations/skybell.markdown @tkdrob source/_integrations/slack.markdown @tkdrob @fletcherau @@ -808,6 +831,7 @@ source/_integrations/smart_home.markdown @starkillerOG source/_integrations/smart_meter_texas.markdown @grahamwetzler source/_integrations/smart_rollos.markdown @starkillerOG source/_integrations/smarther.markdown @cgtobi +source/_integrations/smartthings.markdown @joostlek source/_integrations/smarttub.markdown @mdz source/_integrations/smarty.markdown @z0mbieprocess source/_integrations/smhi.markdown @gjohansson-ST @@ -822,7 +846,7 @@ source/_integrations/solaredge.markdown @frenck @bdraco source/_integrations/solaredge_local.markdown @drobtravels @scheric source/_integrations/solarlog.markdown @Ernst79 @dontinelli source/_integrations/solax.markdown @squishykid @Darsstar -source/_integrations/soma.markdown @ratsept @sebfortier2288 +source/_integrations/soma.markdown @ratsept source/_integrations/somfy.markdown @imicknl source/_integrations/sonarr.markdown @ctalkington source/_integrations/songpal.markdown @rytilahti @shenxn @@ -840,14 +864,13 @@ source/_integrations/starlink.markdown @boswelja source/_integrations/statistics.markdown @ThomDietrich @gjohansson-ST source/_integrations/steam_online.markdown @tkdrob source/_integrations/steamist.markdown @bdraco -source/_integrations/stiebel_eltron.markdown @fucm +source/_integrations/stiebel_eltron.markdown @fucm @ThyMYthOS source/_integrations/stookwijzer.markdown @fwestenberg source/_integrations/stream.markdown @hunterjm @uvjustin @allenporter source/_integrations/stt.markdown @home-assistant/core source/_integrations/subaru.markdown @G-Two source/_integrations/suez_water.markdown @ooii @jb101010-2 source/_integrations/sun.markdown @Swamp-Ig -source/_integrations/sunweg.markdown @rokam source/_integrations/supla.markdown @mwegrzynek source/_integrations/surepetcare.markdown @benleb @danielhiversen source/_integrations/swepco.markdown @tronikos @@ -880,13 +903,14 @@ source/_integrations/tautulli.markdown @ludeeus @tkdrob source/_integrations/technove.markdown @Moustachauve source/_integrations/tedee.markdown @patrickhilker @zweckj source/_integrations/tellduslive.markdown @fredrike -source/_integrations/template.markdown @PhracturedBlue @home-assistant/core +source/_integrations/template.markdown @Petro31 @PhracturedBlue @home-assistant/core source/_integrations/tesla_fleet.markdown @Bre77 source/_integrations/tesla_wall_connector.markdown @einarhauks source/_integrations/teslemetry.markdown @Bre77 source/_integrations/tessie.markdown @Bre77 source/_integrations/text.markdown @home-assistant/core source/_integrations/tfiac.markdown @fredrike @mellado +source/_integrations/thermador.markdown @DavidMStraub @Diegorro98 @MartinHjelmare source/_integrations/thermobeacon.markdown @bdraco source/_integrations/thermoplus.markdown @bdraco source/_integrations/thermopro.markdown @bdraco @h3ss @@ -1020,7 +1044,6 @@ source/_integrations/youless.markdown @gjong source/_integrations/youtube.markdown @joostlek source/_integrations/zabbix.markdown @kruton source/_integrations/zamg.markdown @killer0071234 -source/_integrations/zengge.markdown @emontnemery source/_integrations/zeroconf.markdown @bdraco source/_integrations/zerproc.markdown @emlove source/_integrations/zeversolar.markdown @kvanzuijlen diff --git a/Gemfile b/Gemfile index f7eb241ad8ac..4aeb311cecc7 100644 --- a/Gemfile +++ b/Gemfile @@ -10,9 +10,9 @@ group :development do gem 'stringex', '2.8.6' # > 2.1.0 causes slowdowns https://github.com/sass/sassc-ruby/issues/189 gem 'sassc', '2.1.0' - gem 'sass-embedded', '1.85.1' - gem 'rubocop', '1.74.0' - gem 'ruby-lsp', '0.23.11' + gem 'sass-embedded', '1.87.0' + gem 'rubocop', '1.75.5' + gem 'ruby-lsp', '0.23.17' gem 'rackup', '2.2.1' end @@ -24,7 +24,7 @@ group :jekyll_plugins do end gem 'sinatra', '4.1.1' -gem 'nokogiri', '1.18.4' +gem 'nokogiri', '1.18.8' # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem # and associated library diff --git a/Gemfile.lock b/Gemfile.lock index 7752eefc67de..e3bf3654e2d6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ GEM specs: addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) - ast (2.4.2) + ast (2.4.3) base64 (0.2.0) bigdecimal (3.1.9) chunky_png (1.4.0) @@ -22,18 +22,18 @@ GEM compass-import-once (1.0.5) sass (>= 3.2, < 3.5) concurrent-ruby (1.3.5) - csv (3.3.2) + csv (3.3.4) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) eventmachine (1.2.7) - ffi (1.17.1-arm64-darwin) - ffi (1.17.1-x86_64-linux-gnu) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x86_64-linux-gnu) forwardable-extended (2.6.0) - google-protobuf (4.30.1-arm64-darwin) + google-protobuf (4.30.2-arm64-darwin) bigdecimal rake (>= 13) - google-protobuf (4.30.1-x86_64-linux) + google-protobuf (4.30.2-x86_64-linux) bigdecimal rake (>= 13) http_parser.rb (0.8.0) @@ -70,7 +70,7 @@ GEM nokogiri (~> 1.12) jekyll-watch (2.2.1) listen (~> 3.0) - json (2.10.2) + json (2.11.3) kramdown (2.5.1) rexml (>= 3.3.9) kramdown-parser-gfm (1.1.0) @@ -81,30 +81,30 @@ GEM listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - logger (1.6.6) + logger (1.7.0) mercenary (0.4.0) multi_json (1.15.0) mustermann (3.0.3) ruby2_keywords (~> 0.0.1) - nokogiri (1.18.4-arm64-darwin) + nokogiri (1.18.8-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.4-x86_64-linux-gnu) + nokogiri (1.18.8-x86_64-linux-gnu) racc (~> 1.4) - parallel (1.26.3) - parser (3.3.7.1) + parallel (1.27.0) + parser (3.3.8.0) ast (~> 2.4.1) racc pathutil (0.16.2) forwardable-extended (~> 2.6) - prism (1.3.0) - public_suffix (6.0.1) + prism (1.4.0) + public_suffix (6.0.2) racc (1.8.1) - rack (3.1.12) + rack (3.1.14) rack-protection (4.1.1) base64 (>= 0.1.0) logger (>= 1.6.0) rack (>= 3.0.0, < 4) - rack-session (2.1.0) + rack-session (2.1.1) base64 (>= 0.1.0) rack (>= 3.0.0) rackup (2.2.1) @@ -114,12 +114,12 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rbs (3.8.1) + rbs (3.9.2) logger regexp_parser (2.10.0) rexml (3.4.1) - rouge (4.5.1) - rubocop (1.74.0) + rouge (4.5.2) + rubocop (1.75.5) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -127,12 +127,13 @@ GEM parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.38.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.39.0) - parser (>= 3.3.1.0) - ruby-lsp (0.23.11) + rubocop-ast (1.44.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + ruby-lsp (0.23.17) language_server-protocol (~> 3.17.0) prism (>= 1.2, < 2.0) rbs (>= 3, < 4) @@ -141,9 +142,10 @@ GEM ruby2_keywords (0.0.5) safe_yaml (1.0.5) sass (3.4.25) - sass-embedded (1.85.1) - google-protobuf (~> 4.29) - rake (>= 13) + sass-embedded (1.87.0-arm64-darwin) + google-protobuf (~> 4.30) + sass-embedded (1.87.0-x86_64-linux-gnu) + google-protobuf (~> 4.30) sass-globbing (1.1.5) sass (>= 3.1) sassc (2.1.0) @@ -157,14 +159,14 @@ GEM rack-protection (= 4.1.1) rack-session (>= 2.0.0, < 3) tilt (~> 2.0) - sorbet-runtime (0.5.11934) + sorbet-runtime (0.5.12070) stringex (2.8.6) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) tilt (2.6.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - tzinfo-data (1.2025.1) + tzinfo-data (1.2025.2) tzinfo (>= 1.0.0) unicode-display_width (2.6.0) webrick (1.9.1) @@ -180,12 +182,12 @@ DEPENDENCIES jekyll-paginate (= 1.1.0) jekyll-sitemap (= 1.4.0) jekyll-toc (= 0.19.0) - nokogiri (= 1.18.4) + nokogiri (= 1.18.8) rackup (= 2.2.1) rake (= 13.2.1) - rubocop (= 1.74.0) - ruby-lsp (= 0.23.11) - sass-embedded (= 1.85.1) + rubocop (= 1.75.5) + ruby-lsp (= 0.23.17) + sass-embedded (= 1.87.0) sass-globbing (= 1.1.5) sassc (= 2.1.0) sinatra (= 4.1.1) diff --git a/_config.yml b/_config.yml index c327cbfee398..0e4c692e191e 100644 --- a/_config.yml +++ b/_config.yml @@ -107,9 +107,9 @@ social: # Home Assistant release details current_major_version: 2025 -current_minor_version: 3 -current_patch_version: 3 -date_released: 2025-03-14 +current_minor_version: 5 +current_patch_version: 0 +date_released: 2025-05-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. @@ -248,8 +248,6 @@ installation: key: "rpi5-64" - name: "Raspberry Pi 4" key: "rpi4-64" - - name: "Raspberry Pi 3" - key: "rpi3-64" generic-x86-64: board: Generic x86-64 diff --git a/package-lock.json b/package-lock.json index 412647a80e46..dac42fc14136 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "remark-cli": "^12.0.1", "remark-frontmatter": "^5.0.0", "remark-lint": "^10.0.1", - "remark-lint-fenced-code-flag": "^4.1.1", + "remark-lint-fenced-code-flag": "^4.2.0", "remark-lint-heading-increment": "^4.0.1", "remark-lint-heading-style": "^4.0.1", "remark-lint-no-shell-dollars": "^4.0.1", @@ -20,7 +20,7 @@ "remark-lint-prohibited-strings": "^4.0.0", "remark-lint-unordered-list-marker-style": "^4.0.1", "remark-stringify": "^11.0.0", - "textlint": "^14.5.0", + "textlint": "^14.7.1", "textlint-filter-rule-comments": "^1.2.2", "textlint-rule-common-misspellings": "^1.0.1", "textlint-rule-terminology": "^5.0.13" @@ -427,73 +427,73 @@ "dev": true }, "node_modules/@textlint/ast-tester": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/ast-tester/-/ast-tester-14.5.0.tgz", - "integrity": "sha512-biwtMuv+B1A5tqDLYSwMSjEr24l4zji69Ttg9ZxAEkr5sGre2W5ojEZRA79edDxcAASDF35XgHkWR+tvMsVAdg==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-tester/-/ast-tester-14.7.1.tgz", + "integrity": "sha512-WMXqBRsEaNJowPCASXOqKhu5zu+DL8I6u4R+j3gTHZiBZFXMCLVmBT6pY9ed1i2Owqzj7akYTqjaHJKagGLwxg==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/ast-node-types": "^14.5.0", + "@textlint/ast-node-types": "^14.7.1", "debug": "^4.4.0" } }, "node_modules/@textlint/ast-tester/node_modules/@textlint/ast-node-types": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.5.0.tgz", - "integrity": "sha512-T7NQ2DUnx1zOrnBqcFpJGFgHder5/M7TV596LZTJS/sc1anT7WVrsoGCMmu3oJh2ALg9oJN+PgSmZQ8Mm0Mg+w==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.7.1.tgz", + "integrity": "sha512-7C/xYNZtaG+erIMjNZbRz7av9/S5eC+GAMh0rJ6A9Hik6nS4WyWKblutw2p+O2YWWT2tmOjzu/81fWzzDzmtRg==", "dev": true, "license": "MIT" }, "node_modules/@textlint/ast-traverse": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/ast-traverse/-/ast-traverse-14.5.0.tgz", - "integrity": "sha512-K83si1a2s1LdIVPmzrtuI+SdKjNp2A5jmOcoyXAVNLv3qlJc4DTCyKO7Qn/xTq00zQrhLrZXJSaooBSXi4HXvQ==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-traverse/-/ast-traverse-14.7.1.tgz", + "integrity": "sha512-E9uflmEmr9bUbnX5W+KXoH4c2o5Bu6aimeqadIAixkVjVcYFKL7XJ44HJJx/Ern6hcSSYlbIPHjScjAMTT/kqQ==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/ast-node-types": "^14.5.0" + "@textlint/ast-node-types": "^14.7.1" } }, "node_modules/@textlint/ast-traverse/node_modules/@textlint/ast-node-types": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.5.0.tgz", - "integrity": "sha512-T7NQ2DUnx1zOrnBqcFpJGFgHder5/M7TV596LZTJS/sc1anT7WVrsoGCMmu3oJh2ALg9oJN+PgSmZQ8Mm0Mg+w==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.7.1.tgz", + "integrity": "sha512-7C/xYNZtaG+erIMjNZbRz7av9/S5eC+GAMh0rJ6A9Hik6nS4WyWKblutw2p+O2YWWT2tmOjzu/81fWzzDzmtRg==", "dev": true, "license": "MIT" }, "node_modules/@textlint/config-loader": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/config-loader/-/config-loader-14.5.0.tgz", - "integrity": "sha512-kTFF+Sx3lxH1GSBbk2mEslu0VzyHj9DNy1wiwnPuHrQRVv6fsFZXr35mfLWnfBT40s6aEOrtPh1323jfLduHBg==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/config-loader/-/config-loader-14.7.1.tgz", + "integrity": "sha512-VBsKuqdrurhS8RUVwmMDShqRYm7oBKPHQxJXDKCY1zT1nXUR0y3/9KcZpKXtG1LEfluIteBmZicR/mwobZW56A==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/kernel": "^14.5.0", - "@textlint/module-interop": "^14.5.0", - "@textlint/resolver": "^14.5.0", - "@textlint/types": "^14.5.0", - "@textlint/utils": "^14.5.0", + "@textlint/kernel": "^14.7.1", + "@textlint/module-interop": "^14.7.1", + "@textlint/resolver": "^14.7.1", + "@textlint/types": "^14.7.1", + "@textlint/utils": "^14.7.1", "debug": "^4.4.0", "rc-config-loader": "^4.1.3" } }, "node_modules/@textlint/feature-flag": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/feature-flag/-/feature-flag-14.5.0.tgz", - "integrity": "sha512-fM0W1JRbEkO4IuJhDLDAam50usW+z7B1wA8Y6PciJeojzpTXUiV29MtUISTCfSVkjrDo54aIRgTPn8HogkUGPQ==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/feature-flag/-/feature-flag-14.7.1.tgz", + "integrity": "sha512-yuwNOVPiwDRg+rL0uXzqo9q6g+Ac2T+TETU7RuMxPBlSQWak98I4c8NbjL+aWzL7xj5bZJw5q9MIlOk1jRxl2g==", "dev": true, "license": "MIT" }, "node_modules/@textlint/fixer-formatter": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/fixer-formatter/-/fixer-formatter-14.5.0.tgz", - "integrity": "sha512-vdnrm4tAcJ/KtSiN6szt0MZSWFW8/WKl8kr1owgpQ0NKuxbP1b9dFc+k/V/mq+RnFcuwnbb/r2+7z8oH7HYHEQ==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/fixer-formatter/-/fixer-formatter-14.7.1.tgz", + "integrity": "sha512-AnTLCHnMUNnwRZ3CmeaY15SLzjN3yWH/0OF4R0c+l2v6JF6cdlU907rdcjc9QQnszbaAqn1+fqT+oQ9N9nd5jA==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/module-interop": "^14.5.0", - "@textlint/resolver": "^14.5.0", - "@textlint/types": "^14.5.0", + "@textlint/module-interop": "^14.7.1", + "@textlint/resolver": "^14.7.1", + "@textlint/types": "^14.7.1", "chalk": "^4.1.2", "debug": "^4.4.0", "diff": "^5.2.0", @@ -503,43 +503,43 @@ } }, "node_modules/@textlint/kernel": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/kernel/-/kernel-14.5.0.tgz", - "integrity": "sha512-hgq0b7eUJxEwCf1jNx/DCZeU2SJXXRH+qycvyrGVEOWgLYmtizlCm6GQ+ejDgUdcoNpQhzCkiwV2HF0z9UbmMw==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/kernel/-/kernel-14.7.1.tgz", + "integrity": "sha512-aRzw6jdU3UPKxZpeZtM98OBjx0gGUK1QP3RrNBaLSqKOeSn8q2NkfApVIldBV9oQ+z1Drwmati8Pf3xSExTYew==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/ast-node-types": "^14.5.0", - "@textlint/ast-tester": "^14.5.0", - "@textlint/ast-traverse": "^14.5.0", - "@textlint/feature-flag": "^14.5.0", - "@textlint/source-code-fixer": "^14.5.0", - "@textlint/types": "^14.5.0", - "@textlint/utils": "^14.5.0", + "@textlint/ast-node-types": "^14.7.1", + "@textlint/ast-tester": "^14.7.1", + "@textlint/ast-traverse": "^14.7.1", + "@textlint/feature-flag": "^14.7.1", + "@textlint/source-code-fixer": "^14.7.1", + "@textlint/types": "^14.7.1", + "@textlint/utils": "^14.7.1", "debug": "^4.4.0", "fast-equals": "^4.0.3", "structured-source": "^4.0.0" } }, "node_modules/@textlint/kernel/node_modules/@textlint/ast-node-types": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.5.0.tgz", - "integrity": "sha512-T7NQ2DUnx1zOrnBqcFpJGFgHder5/M7TV596LZTJS/sc1anT7WVrsoGCMmu3oJh2ALg9oJN+PgSmZQ8Mm0Mg+w==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.7.1.tgz", + "integrity": "sha512-7C/xYNZtaG+erIMjNZbRz7av9/S5eC+GAMh0rJ6A9Hik6nS4WyWKblutw2p+O2YWWT2tmOjzu/81fWzzDzmtRg==", "dev": true, "license": "MIT" }, "node_modules/@textlint/linter-formatter": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/linter-formatter/-/linter-formatter-14.5.0.tgz", - "integrity": "sha512-5QQsdnsuUBscCq1IX10ynYtsfLmctdoc4GZtJA7L//QFYAAgTrBzpXjfhyWZs7C5VJho9FzfljyuuA7jbhRrFw==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/linter-formatter/-/linter-formatter-14.7.1.tgz", + "integrity": "sha512-saAE+e4RZFInRmCF9pu7ukZAHxWaYw9WIA1PptYHItCnlyGS7WB7cYHilkj4coWGr3xGaQ2qAjqX/QIbVE7QGA==", "dev": true, "license": "MIT", "dependencies": { "@azu/format-text": "^1.0.2", "@azu/style-format": "^1.0.1", - "@textlint/module-interop": "^14.5.0", - "@textlint/resolver": "^14.5.0", - "@textlint/types": "^14.5.0", + "@textlint/module-interop": "^14.7.1", + "@textlint/resolver": "^14.7.1", + "@textlint/types": "^14.7.1", "chalk": "^4.1.2", "debug": "^4.4.0", "js-yaml": "^3.14.1", @@ -552,13 +552,13 @@ } }, "node_modules/@textlint/markdown-to-ast": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/markdown-to-ast/-/markdown-to-ast-14.5.0.tgz", - "integrity": "sha512-qftHkBnyWEy2PmAhmhrmTemCKMJCpPKtFZt0woaa0yZkMwXo/RN66elnjAEJZenkRntQgphlKJJZ0I/NA2hH4g==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/markdown-to-ast/-/markdown-to-ast-14.7.1.tgz", + "integrity": "sha512-aKIJi1FZj8PYr/n9EYFsifofT2XNPDX9E/24PiFMNBjiOfovCayOpfn6iuqNEo3CEPx7w4d20rQOUnxD+GYzhg==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/ast-node-types": "^14.5.0", + "@textlint/ast-node-types": "^14.7.1", "debug": "^4.4.0", "mdast-util-gfm-autolink-literal": "^0.1.3", "neotraverse": "^0.6.15", @@ -570,9 +570,9 @@ } }, "node_modules/@textlint/markdown-to-ast/node_modules/@textlint/ast-node-types": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.5.0.tgz", - "integrity": "sha512-T7NQ2DUnx1zOrnBqcFpJGFgHder5/M7TV596LZTJS/sc1anT7WVrsoGCMmu3oJh2ALg9oJN+PgSmZQ8Mm0Mg+w==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.7.1.tgz", + "integrity": "sha512-7C/xYNZtaG+erIMjNZbRz7av9/S5eC+GAMh0rJ6A9Hik6nS4WyWKblutw2p+O2YWWT2tmOjzu/81fWzzDzmtRg==", "dev": true, "license": "MIT" }, @@ -819,88 +819,88 @@ } }, "node_modules/@textlint/module-interop": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/module-interop/-/module-interop-14.5.0.tgz", - "integrity": "sha512-nlFwHSYZJgSwXyF9PuHV3DcvRnObf64Mm4QWt9LaTr5zQB2MwEluaL8ROYL+sLJ4JhqNKpuqBT1EkTixPsN3cQ==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/module-interop/-/module-interop-14.7.1.tgz", + "integrity": "sha512-9mfLErTFx8N+tZNTL+46YCY/jnCDOJKpceng5WVwDeZeMJbewhjY3PVcxMoPnvPT10QnE/hDk3b6riUYckgHgw==", "dev": true, "license": "MIT" }, "node_modules/@textlint/resolver": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/resolver/-/resolver-14.5.0.tgz", - "integrity": "sha512-yvC8gQHKsl/rR3x+884tA9BzVn6naILmHRmOP3FEQogr+ixOW4rL9OgdS6IoMjG8cVh8o4kI40xJfh1l6oX6vQ==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/resolver/-/resolver-14.7.1.tgz", + "integrity": "sha512-lQ5ATfpsOgiYnwe2aoS0t9uJ4SrvyiCJpfJdqUQZCVL161O/yMKZBc6nwsyBlruEcFoNxK06F3s3IIV4EsI12A==", "dev": true, "license": "MIT" }, "node_modules/@textlint/source-code-fixer": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/source-code-fixer/-/source-code-fixer-14.5.0.tgz", - "integrity": "sha512-zcokW+MBTppOzGumeB1SZvjDitCnO2sAZrWpmw849L6P11RdxS/iQXakg4jkRTTlWYR1AtzyAa9j0lLCdxsfuQ==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/source-code-fixer/-/source-code-fixer-14.7.1.tgz", + "integrity": "sha512-2teYM26+mwFhKaPKYiKjTH3gInjBFJRMPrd2t+WO8NkZnVCrCq0IdWNJYAP34zBd1JLgXAK0EL93Mo+RPwCtcQ==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/types": "^14.5.0", + "@textlint/types": "^14.7.1", "debug": "^4.4.0" } }, "node_modules/@textlint/text-to-ast": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/text-to-ast/-/text-to-ast-14.5.0.tgz", - "integrity": "sha512-e6SrPeCScmxxfTDpXo+nBh4tt6sbqySX/fE65sYVYupLwpJsCtxTEnYft2jEqifvgaM4JjgzETSQMG799HBTPw==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/text-to-ast/-/text-to-ast-14.7.1.tgz", + "integrity": "sha512-sSyWYdsX407xMiTKqnB5xWW4ft9SyxwFW2sY3Cpl0emoH5x1CLiYnxpW8uLIN/eFWiSzQlKU9UpyHFfozSC3Ag==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/ast-node-types": "^14.5.0" + "@textlint/ast-node-types": "^14.7.1" } }, "node_modules/@textlint/text-to-ast/node_modules/@textlint/ast-node-types": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.5.0.tgz", - "integrity": "sha512-T7NQ2DUnx1zOrnBqcFpJGFgHder5/M7TV596LZTJS/sc1anT7WVrsoGCMmu3oJh2ALg9oJN+PgSmZQ8Mm0Mg+w==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.7.1.tgz", + "integrity": "sha512-7C/xYNZtaG+erIMjNZbRz7av9/S5eC+GAMh0rJ6A9Hik6nS4WyWKblutw2p+O2YWWT2tmOjzu/81fWzzDzmtRg==", "dev": true, "license": "MIT" }, "node_modules/@textlint/textlint-plugin-markdown": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/textlint-plugin-markdown/-/textlint-plugin-markdown-14.5.0.tgz", - "integrity": "sha512-riMcW6Sj/IvTnIAA4W0O5pxJxdqth+MUe2li7wg8yCq3jilS0EYIlolNXvX414v/9swsLu8Tztwugrh0E6HJDw==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/textlint-plugin-markdown/-/textlint-plugin-markdown-14.7.1.tgz", + "integrity": "sha512-FnxwOOvvkIZ7HPV4gV0ZU6mA+G6LhA5QdspUqXAqTPQ0SY7X95PfQYbzk8Yz4RNyXFMhIcviKLO4+eSyBBTSuw==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/markdown-to-ast": "^14.5.0" + "@textlint/markdown-to-ast": "^14.7.1" } }, "node_modules/@textlint/textlint-plugin-text": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/textlint-plugin-text/-/textlint-plugin-text-14.5.0.tgz", - "integrity": "sha512-aASQwkRnupRlY9w168SBjrsDbO1wtg2EYx8JSnt/YboUnhszQD8Zys178Zu/00ECtpxwpjQYowoYNq0BoP9aig==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/textlint-plugin-text/-/textlint-plugin-text-14.7.1.tgz", + "integrity": "sha512-Cq1pmUWU95W2cYpXr9GDkKm5RN5XAPwVThFeMtj6RE4bCS+qqH/2O08yhUobKo0ryKb7j1zzBi/QdQ2U34YwvQ==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/text-to-ast": "^14.5.0" + "@textlint/text-to-ast": "^14.7.1" } }, "node_modules/@textlint/types": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/types/-/types-14.5.0.tgz", - "integrity": "sha512-z+oJS5GHK5KiV87ZNCYAQnZTgq1MRGl9g301GOV6Zq4RjH75JVQPNa4hUlwzG2sF6jks+wLhMjxwaQaG6cKCpA==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/types/-/types-14.7.1.tgz", + "integrity": "sha512-j10OEEHRAaqGMC6dK3+H1Eg3bksASGTmGDozsSepYs7qInY+lYBCe5m3JTrKkDnAX4nNy8ninnKzrYKcVkWahw==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/ast-node-types": "^14.5.0" + "@textlint/ast-node-types": "^14.7.1" } }, "node_modules/@textlint/types/node_modules/@textlint/ast-node-types": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.5.0.tgz", - "integrity": "sha512-T7NQ2DUnx1zOrnBqcFpJGFgHder5/M7TV596LZTJS/sc1anT7WVrsoGCMmu3oJh2ALg9oJN+PgSmZQ8Mm0Mg+w==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.7.1.tgz", + "integrity": "sha512-7C/xYNZtaG+erIMjNZbRz7av9/S5eC+GAMh0rJ6A9Hik6nS4WyWKblutw2p+O2YWWT2tmOjzu/81fWzzDzmtRg==", "dev": true, "license": "MIT" }, "node_modules/@textlint/utils": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/utils/-/utils-14.5.0.tgz", - "integrity": "sha512-gAKZh1woc0IZGoVjQ8G8Og10dsBJ6UxaCFXofeHveWsZhJAdVzjw49/tJLVu/39t8GTdZQ4BAHuNxHNFgLN57w==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/utils/-/utils-14.7.1.tgz", + "integrity": "sha512-nvIOltt0U5HQzu28qfYgbXUvZxEZBPRnQZHqlwMsqKp55bZ5L3iSNYwHvCej7fm9GOXH7Yz3UzLSko9eF5m3PA==", "dev": true, "license": "MIT" }, @@ -4427,9 +4427,9 @@ } }, "node_modules/remark-lint-fenced-code-flag": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-4.1.1.tgz", - "integrity": "sha512-hKPqowc79jrJL47AfnqDThvE8Q249nHCleR5nxuf9ybriMqcAHYxragKzU5c4W1fNy20bTfFdZz/iAAQAk9kwg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-4.2.0.tgz", + "integrity": "sha512-QWGTrnYbcopOFZR98djDREmKApLonJ7hmXE7pEcOGee9JY/EUIVS7Lq54Hy9CtU3cVIvQQmiMTxCwUhfddDJFA==", "dev": true, "license": "MIT", "dependencies": { @@ -6107,25 +6107,25 @@ "dev": true }, "node_modules/textlint": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/textlint/-/textlint-14.5.0.tgz", - "integrity": "sha512-+C5zYpEv0HsQAuz6crm4BjuMXaHi6gKTSwqZZttHI2Jm/WGtpza2SbZxct+STdMgN1XbINcsP58gZ4juQwokcw==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/textlint/-/textlint-14.7.1.tgz", + "integrity": "sha512-jhWEeF3SWYPuItcTRLA1KAyxHAX2diWpqtglcagPzPidFi2OMKCNW55FlaIQvOkWdohp5LzFk0mv4XiChqGr0Q==", "dev": true, "license": "MIT", "dependencies": { - "@textlint/ast-node-types": "^14.5.0", - "@textlint/ast-traverse": "^14.5.0", - "@textlint/config-loader": "^14.5.0", - "@textlint/feature-flag": "^14.5.0", - "@textlint/fixer-formatter": "^14.5.0", - "@textlint/kernel": "^14.5.0", - "@textlint/linter-formatter": "^14.5.0", - "@textlint/module-interop": "^14.5.0", - "@textlint/resolver": "^14.5.0", - "@textlint/textlint-plugin-markdown": "^14.5.0", - "@textlint/textlint-plugin-text": "^14.5.0", - "@textlint/types": "^14.5.0", - "@textlint/utils": "^14.5.0", + "@textlint/ast-node-types": "^14.7.1", + "@textlint/ast-traverse": "^14.7.1", + "@textlint/config-loader": "^14.7.1", + "@textlint/feature-flag": "^14.7.1", + "@textlint/fixer-formatter": "^14.7.1", + "@textlint/kernel": "^14.7.1", + "@textlint/linter-formatter": "^14.7.1", + "@textlint/module-interop": "^14.7.1", + "@textlint/resolver": "^14.7.1", + "@textlint/textlint-plugin-markdown": "^14.7.1", + "@textlint/textlint-plugin-text": "^14.7.1", + "@textlint/types": "^14.7.1", + "@textlint/utils": "^14.7.1", "debug": "^4.4.0", "file-entry-cache": "^10.0.5", "get-stdin": "^5.0.1", @@ -6250,9 +6250,9 @@ } }, "node_modules/textlint/node_modules/@textlint/ast-node-types": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.5.0.tgz", - "integrity": "sha512-T7NQ2DUnx1zOrnBqcFpJGFgHder5/M7TV596LZTJS/sc1anT7WVrsoGCMmu3oJh2ALg9oJN+PgSmZQ8Mm0Mg+w==", + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-14.7.1.tgz", + "integrity": "sha512-7C/xYNZtaG+erIMjNZbRz7av9/S5eC+GAMh0rJ6A9Hik6nS4WyWKblutw2p+O2YWWT2tmOjzu/81fWzzDzmtRg==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index bc92d01c6cb4..4063f65c1d31 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "remark-cli": "^12.0.1", "remark-frontmatter": "^5.0.0", "remark-lint": "^10.0.1", - "remark-lint-fenced-code-flag": "^4.1.1", + "remark-lint-fenced-code-flag": "^4.2.0", "remark-lint-heading-increment": "^4.0.1", "remark-lint-heading-style": "^4.0.1", "remark-lint-no-shell-dollars": "^4.0.1", @@ -15,7 +15,7 @@ "remark-lint-prohibited-strings": "^4.0.0", "remark-lint-unordered-list-marker-style": "^4.0.1", "remark-stringify": "^11.0.0", - "textlint": "^14.5.0", + "textlint": "^14.7.1", "textlint-filter-rule-comments": "^1.2.2", "textlint-rule-common-misspellings": "^1.0.1", "textlint-rule-terminology": "^5.0.13" diff --git a/sass/homeassistant/pages/_component_page.scss b/sass/homeassistant/pages/_component_page.scss index 0a30a85239e6..91ee4fca71ae 100644 --- a/sass/homeassistant/pages/_component_page.scss +++ b/sass/homeassistant/pages/_component_page.scss @@ -44,7 +44,7 @@ width: fit-content; font-size: 1rem; box-shadow: none; - background-color: $blue; + background-color: $blueDark; color: white; border-radius: 24px; @@ -63,7 +63,7 @@ background-color: white; &:checked { - background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22%231abcf2%22%20transform%3D%22rotate(90)%22%3E%3Ccircle%20cx%3D%228%22%20cy%3D%228%22%20r%3D%223%22%2F%3E%3C%2Fsvg%3E"); + background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22%23007fa8%22%20transform%3D%22rotate(90)%22%3E%3Ccircle%20cx%3D%228%22%20cy%3D%228%22%20r%3D%223%22%2F%3E%3C%2Fsvg%3E"); } } @@ -100,7 +100,7 @@ text-align-last: center; font-size: 16px; line-height: 24px; - border: 2px solid $primary-color; + border: 2px solid $blueDark; border-top-right-radius: 0px; border-top-left-radius: 0px; border-bottom-right-radius: 5px; @@ -117,7 +117,7 @@ } .filter-title { - background: $primary-color; + background: $blueDark; color: white; text-align: center; border-top-right-radius: 5px; @@ -135,7 +135,7 @@ margin: 10px 5px 0px 0px; padding: 5px 10px; min-width: 100px; - background-color: $primary-color; + background-color: $blueDark; border-radius: 28px; border: none; color: white; diff --git a/sass/homeassistant/plugins/_alert.scss b/sass/homeassistant/plugins/_alert.scss index 39e6e115088c..9da28658222e 100644 --- a/sass/homeassistant/plugins/_alert.scss +++ b/sass/homeassistant/plugins/_alert.scss @@ -1,55 +1,62 @@ div.alert { - position: relative; - background: #e7f2fa; - - padding: 20px 24px 20px 24px; - margin-bottom: 24px; border-radius: 16px; + margin-bottom: 24px; + padding: 20px 24px 20px 24px; + position: relative; + + >:last-child { + margin-bottom: 0; + } p { - margin-bottom: 0px; &.alert-title { font-weight: bold; line-height: 1.5em; } + &.alert-content { padding: 6px; } } &.alert-note { + background-color: #e7f2fa; + p.alert-title { color: #6ab0de; } - background-color: #e7f2fa; } &.alert-tip { + background-color: #e6f4ea; + p.alert-title { color: #4caf50; } - background-color: #e6f4ea; } &.alert-important { + background-color: #ede7f6; + p.alert-title { color: #7e57c2; } - background-color: #ede7f6; } &.alert-warning { + background-color: #f7f9e1; + p.alert-title { color: rgb(187, 185, 13); } - background-color: #f7f9e1; } &.alert-caution { + background-color: #fdecea; + p.alert-title { color: #d32f2f; } - background-color: #fdecea; } -} +} \ No newline at end of file diff --git a/source/_dashboards/area.markdown b/source/_dashboards/area.markdown index be21b487ee8f..13d009bdb0dd 100644 --- a/source/_dashboards/area.markdown +++ b/source/_dashboards/area.markdown @@ -8,6 +8,10 @@ related: title: Themes - docs: /dashboards/cards/ title: Dashboard cards + - docs: /dashboards/dashboards/#areas-dashboard + title: Areas dashboard + - docs: /docs/organizing/areas/ + title: About areas --- The area card lets you control and monitor an individual {% term area %}. diff --git a/source/_dashboards/clock.markdown b/source/_dashboards/clock.markdown new file mode 100644 index 000000000000..e46deac1691e --- /dev/null +++ b/source/_dashboards/clock.markdown @@ -0,0 +1,109 @@ +--- +type: card +title: "Clock card" +sidebar_label: Clock +description: "The Clock card shows the current time in a variety of formats and sizes." +related: + - docs: /docs/frontend/#user--or-browser-dependent-settings + title: Setup your time format and timezone +--- + +The Clock card shows the current time in a variety of formats, sizes and time zones. + +

+Screenshot of the clock card +Screenshot of the clock card +

+ +{% include dashboard/edit_dashboard.md %} + +All options for this card can be configured via the user interface. + + +## Card settings + +{% configuration_basic %} +Title: + description: Adds a title to the top of the card +Clock Size: + description: Adjusts the size of the text allowing a wider range of use with different types of dashboards. Defaults to small. +Display Seconds: + description: Shows seconds alongside the clock, providing the time format is in a 12-hour format. +Time Format: + description: Allows the time format to be changed on a per-card level. Defaults to the user profile setting. +Time Zone: + description: Change the timezone used for the time on a per-card level. Defaults to the user profile setting. +{% endconfiguration_basic %} + +### Examples + +Basic example: + +```yaml +type: clock +``` + +

+Screenshot of the basic clock card +Screenshot of the basic clock card +

+ + +Example of a larger clock card for tablet dashboards: + +```yaml +type: clock +clock_size: large +time_format: "12" +show_seconds: true +``` + +

+Screenshot of a large sized, 12 hour clock card showing am/pm and seconds +Screenshot of a large sized, 12 hour clock card showing am/pm and seconds +

+ +A medium-sized clock card better suited for desktop dashboards: + +```yaml +type: clock +clock_size: medium +time_format: "12" +show_seconds: false +``` + +

+Screenshot of a medium sized, 12 hour clock showing am/pm +Screenshot of a medium sized, 12 hour clock showing am/pm +

+ +A medium-sized, 24 hour clock using the London timezone with a title + +```yaml +type: clock +clock_size: medium +time_zone: Europe/London +title: London 💂 + +``` + +

+Screenshot of a medium sized, 24 hour clock showing seconds based in London along with a title +Screenshot of a medium sized, 24 hour clock showing seconds based in London along with a title +

+ +A medium-sized, 12 hour clock using the New York timezone with a title + +```yaml +type: clock +clock_size: medium +time_format: "12" +time_zone: America/New_York +title: New York 🦅 + +``` + +

+Screenshot of a medium sized, 12 hour clock showing am/pm and seconds based in New York along with a title +Screenshot of a medium sized, 12 hour clock showing am/pm and seconds based in New York along with a title +

diff --git a/source/_dashboards/energy.markdown b/source/_dashboards/energy.markdown index 411d6611fc28..0d9219c8a77f 100644 --- a/source/_dashboards/energy.markdown +++ b/source/_dashboards/energy.markdown @@ -12,7 +12,7 @@ related: This is a list of all the cards used in the energy dashboard. You can also place them anywhere you want in your dashboard. -Currently, there are no configuration options available for these cards. You can configure them on the {% my config_energy title="energy configuration page" %}. +You can configure them on the {% my config_energy title="energy configuration page" %}. ## Energy date picker @@ -244,6 +244,35 @@ max_devices: 5 The sankey energy graph shows the flow of energy in your home. It starts with sources and flows into the various consumers. Devices are grouped into floors and areas if these are configured. +### YAML configuration + +The following YAML options are available + +{% configuration %} +type: + required: true + description: "`energy-sankey`" + type: string +title: + required: false + description: The title of the card. + type: string +layout: + required: false + description: "`vertical` or `horizontal`. Determines the orientation (flow direction) of the card" + type: string +group_by_area: + required: false + description: Whether to group the devices by area + type: boolean + default: true +group_by_floor: + required: false + description: Whether to group the devices by floor + type: boolean + default: true +{% endconfiguration %} + ### Examples ```yaml diff --git a/source/_dashboards/heading.markdown b/source/_dashboards/heading.markdown index 3c325d36a6f7..9a444048546b 100644 --- a/source/_dashboards/heading.markdown +++ b/source/_dashboards/heading.markdown @@ -60,7 +60,7 @@ badges: ## Heading badges -In addition to the heading text, each heading card can show small badges. They are smaller than regular [badges](/dashboards/badges/) and don't have a background. The heading badges can display sensor information in a compact and minimal style. +In addition to the heading text, each heading card can show small badges. They are smaller than regular [badges](/dashboards/badges/) and don't have a background. The heading badges can display sensor information in a compact and minimal style. Heading badges also support [actions](/dashboards/actions/). ```yaml type: entity @@ -108,4 +108,12 @@ tap_action: required: false description: Action taken on card tap. See [action documentation](/dashboards/actions/#tap-action). By default, it will do nothing. type: map +hold_action: + required: false + description: Action taken on card hold. See [action documentation](/dashboards/actions/#hold-action). By default, it will do nothing. + type: map +double_tap_action: + required: false + description: Action taken on card double tap. See [action documentation](/dashboards/actions/#double-tap-action). By default, it will do nothing. + type: map {% endconfiguration %} diff --git a/source/_dashboards/history-graph.markdown b/source/_dashboards/history-graph.markdown index b1f6bdf0ef85..3a0e1e8b3b79 100644 --- a/source/_dashboards/history-graph.markdown +++ b/source/_dashboards/history-graph.markdown @@ -93,6 +93,12 @@ name: type: string {% endconfiguration %} +### Long term statistics + +Home Assistant saves long-term statistics for a sensor if the entity has a state_class of measurement, total, or total_increasing. For short-term statistics, a snapshot is taken every 5 minutes. For long-term statistics, an hourly aggregate is stored of the short-term statistics. Short-term statistics are automatically purged after a predefined period (default is 10 days). Long-term statistics are never purged. + +In the history graph card, if the hours to show variable is set to a figure higher than the purge_keep period, long-term statistics will be used, with short term statistics shown in bold. + ### Examples ```yaml diff --git a/source/_dashboards/iframe.markdown b/source/_dashboards/iframe.markdown index 089db8e9bb2c..0bd7daf027bf 100644 --- a/source/_dashboards/iframe.markdown +++ b/source/_dashboards/iframe.markdown @@ -61,6 +61,11 @@ allow: description: The [Permissions Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy#iframes) of the iframe, that is, the value of the [`allow`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#allow) attribute. type: string default: "fullscreen" +disable_sandbox: + required: false + description: Disables the [sandbox](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox) attribute of the iframe, e.g. required for Chrome when viewing PDFs. This is less secure and should only be used if you trust the content of the iframe. + type: boolean + default: false {% endconfiguration %} ### Examples diff --git a/source/_dashboards/map.markdown b/source/_dashboards/map.markdown index 58b227afa0ce..e16e352197a5 100644 --- a/source/_dashboards/map.markdown +++ b/source/_dashboards/map.markdown @@ -130,7 +130,11 @@ name: label_mode: required: false default: name - description: When set to `icon`, renders the entity's icon in the marker instead of text. When set to `state`, renders the entity's state as the label for the map marker instead of the entity's name. This option doesn't apply to [zone](/integrations/zone/) entities because they don't use a label but an icon. + description: When set to `icon`, renders the entity's icon in the marker instead of text. When set to `state` or `attribute`, renders the entity's state or attribute as the label for the map marker instead of the entity's name. This option doesn't apply to [zone](/integrations/zone/) entities because they don't use a label but an icon. + type: string +attribute: + required: false + description: An entity's attribute when `label_mode` set to `attribute`. type: string focus: required: false @@ -151,8 +155,12 @@ source: label_mode: required: false default: name - description: When set to `icon`, renders the geolocation entity's icon in the marker instead of text. When set to `state`, renders the entity's state as the label for the map marker instead of the entity's name. - type: string + description: When set to `icon`, renders the entity's icon in the marker instead of text. When set to `state` or `attribute`, renders the entity's state or attribute as the label for the map marker instead of the entity's name. This option doesn't apply to [zone](/integrations/zone/) entities because they don't use a label but an icon. + type: string +attribute: + required: false + description: An entity's attribute when `label_mode` set to `attribute`. + type: string focus: required: false default: true diff --git a/source/_dashboards/picture-glance.markdown b/source/_dashboards/picture-glance.markdown index 4a6626a3e7c4..4add509da4c8 100644 --- a/source/_dashboards/picture-glance.markdown +++ b/source/_dashboards/picture-glance.markdown @@ -72,6 +72,11 @@ aspect_ratio: required: false description: 'Forces the height of the image to be a ratio of the width. Valid formats: Height percentage value (`23%`) or ratio expressed with colon or "x" separator (`16:9` or `16x9`). For a ratio, the second element can be omitted and will default to "1" (`1.78` equals `1.78:1`).' type: string +fit_mode: + required: false + description: 'Defines the manner in which the image is stretched/clipped to fit the card area. `cover`: The image keeps its aspect ratio and fills the given dimension. The image will be clipped to fit. `contain`: The image keeps its aspect ratio, but is resized to fit within the given dimension. `fill`: The image is resized to fill the given dimension. If necessary, the image will be stretched or squished to fit.' + type: string + default: cover entity: required: false description: Entity to use for `state_image` and `state_filter`. diff --git a/source/_dashboards/statistics-graph.markdown b/source/_dashboards/statistics-graph.markdown index 2860351b4332..6f6c27e7905a 100644 --- a/source/_dashboards/statistics-graph.markdown +++ b/source/_dashboards/statistics-graph.markdown @@ -22,7 +22,7 @@ Screenshot of the statistics graph card with none metered entities and `chart_ty Screenshot of the statistics graph card with a metered entity and `chart_type` `bar`.

-Statistics are gathered every 5 minutes and also hourly for sensors that support it. The 5-minute statistics will be retained for the duration set in the [recorder configuration](/integrations/recorder/#purge_keep_days), and hourly statistics will be retained indefinitely. It will either keep the `min`, `max`, and `mean` of a sensor's value for a specific hour or the `sum` for a metered entity. +Statistics are gathered every 5 minutes and also hourly for sensors with a state_class of measurement, total or total_increasing. The 5-minute statistics will be retained for the duration set in the [recorder configuration](/integrations/recorder/#purge_keep_days), and hourly statistics will be retained indefinitely. It will either keep the `min`, `max`, and `mean` of a sensor's value for a specific hour or the `sum` for a metered entity. If your sensor doesn't work with statistics, check [this](/more-info/statistics/). diff --git a/source/_data/glossary.yml b/source/_data/glossary.yml index 9a294ae29351..f9987bbe9e1e 100644 --- a/source/_data/glossary.yml +++ b/source/_data/glossary.yml @@ -39,9 +39,10 @@ excerpt: > Add-ons are additional standalone third-party software packages that can be installed on Home Assistant OS. + link: /getting-started/concepts-terminology/#add-ons - term: Area definition: >- - An area in Home Assistant is a logical grouping of devices and entities that + An area in Home Assistant is a [logical grouping](/docs/organizing/) of devices and entities that are meant to match areas (or rooms) in the physical world: your home. For example, the `living room` area groups devices and entities in your living room. Areas allow you to target actions at an entire group of devices. @@ -50,12 +51,13 @@ floors. Areas can also be used for automatically generated cards, such as the [Area card](/dashboards/area/). excerpt: >- - An area in Home Assistant is a logical grouping of devices and entities that + An area in Home Assistant is a [logical grouping](/docs/organizing/) of devices and entities that are meant to match areas (or rooms) in the physical world: your home. For example, the `living room` area groups devices and entities in your living room. aliases: - areas + link: /docs/organizing/areas/ - term: Automation definition: >- Automations connect one or more triggers to one or more actions in a 'when @@ -74,12 +76,9 @@ definition: >- Home Assistant has built-in functionality to create files containing a copy of your configuration. This can be used to restore your Home Assistant as - well as migrate to a new system. The backup feature is available on some - installation types. - link: /integrations/backup/ - excerpt: >- - Home Assistant has built-in functionality to create files containing a copy - of your configurations. This is available on certain installation types. + well as migrate to a new system. The backup feature is available for all + [installation types](/installation/#advanced-installation-methods). + link: /common-tasks/general/#backups aliases: - backups - term: Binary sensor @@ -92,7 +91,7 @@ - binary_sensors - term: Blueprint definition: >- - A blueprint is a script, automation or template entity configuration with certain parts + A blueprint is a [script](/getting-started/concepts-terminology/#scripts), [automation](/getting-started/concepts-terminology/#automation), or [template](/integrations/template/) entity configuration with certain parts marked as configurable. This allows users to create multiple scripts, automations or template entities based on the same blueprint, with each having its own configuration-specific settings. Blueprints are shared by the community on @@ -100,11 +99,6 @@ exchange](https://community.home-assistant.io/c/blueprints-exchange/53) in the forum. link: /docs/blueprint/ - excerpt: >- - A blueprint is a script, automation or template entity configuration with certain parts - marked as configurable. This allows users to create multiple scripts, - automations or template entities based on the same blueprint, with each having its own - configuration-specific settings. aliases: - blueprints - term: Button @@ -116,7 +110,7 @@ - buttons - term: Category definition: >- - A category is an organization tool that allows grouping items in a table. + A category is an organization tool that allows [grouping](/docs/organizing/) items in a table. Like labels, categories allow grouping irrespective of the items' physical location. For example, on the automations page, you can create the categories “Notifications” or “NFC tags” to view your automations grouped or @@ -124,6 +118,7 @@ have different categories than the scene, scripts, or helpers settings page. aliases: - categories + link: /docs/organizing/categories/ - term: Climate definition: >- The Climate entity allows you to control and monitor HVAC (heating, @@ -261,9 +256,15 @@ link: /docs/configuration/events/ aliases: - events +- term: Event entity + definition: >- + Events are signals that are emitted when something happens, for example, + when a user presses a physical button like a doorbell or when a button on a + remote control is pressed. + link: /integrations/event - term: Floor definition: >- - A floor in Home Assistant is a logical grouping of areas that are meant to + A floor in Home Assistant is a [logical grouping](/docs/organizing/) of areas that are meant to match the physical floors in your home. Devices & entities are not assigned to floors but to areas. A floor has properties such as: Floor ID, name, aliases (for use in assistants), an icon, and a floor level. Some of these @@ -272,13 +273,14 @@ target for actions. For example, to turn off all the lights on the downstairs floor when you go to bed. excerpt: >- - A floor in Home Assistant is a logical grouping of areas that are meant to + A floor in Home Assistant is a [logical grouping](/docs/organizing/) of areas that are meant to match the physical floors in your home. Devices & entities are not assigned to floors but to areas. Floors can be used in automations and scripts as a target for actions. For example, to turn off all the lights on the downstairs floor when you go to bed. aliases: - floors + link: /docs/organizing/floors/ - term: Frontend definition: >- The frontend is a necessary component for the UI, it is also where you can @@ -405,7 +407,7 @@ - Intents - term: Label definition: >- - Labels in Home Assistant allow grouping elements irrespective of their + Labels in Home Assistant allow [grouping](/docs/organizing/) elements irrespective of their physical location or type. Labels can be assigned to areas, devices, entities, automations, scenes, scripts, and helpers. Labels can be used in automations and scripts as a target for actions. Labels can @@ -413,13 +415,14 @@ to show only devices with the label `heavy energy usage` or turn these devices off when there is not a lot of solar energy available. excerpt: >- - Labels in Home Assistant allow grouping elements irrespective of their + Labels in Home Assistant allow [grouping](/docs/organizing/) elements irrespective of their physical location or type. Labels can be assigned to areas, devices, entities, automations, scenes, scripts, and helpers. Labels can be used in automations and scripts as a target for actions. Labels can also be used to filter data. aliases: - labels + link: /docs/organizing/labels/ - term: Lovelace definition: >- Lovelace is the original code name of the UI that is now known as [Home diff --git a/source/_data/products.yml b/source/_data/products.yml index 89e60fe5e96b..15ed52da65f3 100644 --- a/source/_data/products.yml +++ b/source/_data/products.yml @@ -46,7 +46,7 @@ green: logo: /images/distributors/smarthome.webp # Europe - name: Alza.cz - ship_from: Czechia + ship_from: Czech Republic ship_to: Europe url: https://www.alza.cz/home-assistant-green-d7998187.htm logo: /images/distributors/alza-cz.webp @@ -222,6 +222,11 @@ yellow: ship_to: Europe url: https://thepihut.com/products/home-assistant-yellow logo: /images/distributors/pi-hut.webp + - name: Domadoo + ship_from: France + ship_to: Europe + url: https://www.domadoo.fr/en/smart-home-hub/7113-nabu-casa-home-assistant-yellow-kit-with-power-supply.html + logo: /images/distributors/domadoo.jpg zbt-1: name: "Home Assistant Connect ZBT-1" distributors: @@ -402,7 +407,7 @@ voice-pe: logo: /images/distributors/smart-guys.webp # Europe - name: Alza.cz - ship_from: Czechia + ship_from: Czech Republic ship_to: Europe url: https://www.alza.cz/home-assistant-voice-preview-edition-d12741248.htm logo: /images/distributors/alza-cz.webp @@ -481,3 +486,8 @@ voice-pe: ship_to: Europe url: https://www.pi-shop.ch/home-assistant-voice-preview-edition logo: /images/distributors/pi-shop.webp + - name: ROBBshop + ship_from: Netherlands + ship_to: Europe + url: https://www.robbshop.nl/home-assistant-voice-preview-edition + logo: /images/distributors/robb.webp diff --git a/source/_docs/automation/action.markdown b/source/_docs/automation/action.markdown index 25c6d702c8f5..85467c5c6582 100644 --- a/source/_docs/automation/action.markdown +++ b/source/_docs/automation/action.markdown @@ -3,7 +3,7 @@ title: "Automation actions" description: "Automations result in action." --- -The action of an automation rule is what is being executed when a rule fires. The action part follows the [script syntax](/docs/scripts/) which can be used to interact with anything via other actions or events. +The action of an automation is what is being executed when an automation fires. The action part follows the [script syntax](/docs/scripts/) which can be used to interact with anything via other actions or events. For actions, you can specify the `entity_id` that it should apply to and optional parameters (to specify for example the brightness). diff --git a/source/_docs/automation/basics.markdown b/source/_docs/automation/basics.markdown index 53fdb31f4fcf..892244674549 100644 --- a/source/_docs/automation/basics.markdown +++ b/source/_docs/automation/basics.markdown @@ -15,24 +15,31 @@ 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 {% term events %} that should trigger the automation rule. In this case, it is a person arriving home, which can be observed in Home Assistant using {% term devices %}/{% term sensors %} by observing the state of Paulus changing from `not_home` to `home`. +The first part is the [trigger](/docs/automation/trigger/) of the automation. Triggers describe {% term events %} that should trigger the automation. In this case, it is a person arriving home, which can be observed in Home Assistant using {% term devices %}/{% term sensors %} 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. +The second part is the [condition](/docs/automation/condition/). Conditions are optional tests that can limit an automation 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. -The third part is the [action](/docs/automation/action/), which will be performed when a rule is triggered and all conditions are met. For example, it can turn a light on, set the temperature on your thermostat or activate a scene. +The third part is the [action](/docs/automation/action/), which will be performed when an automation is triggered and all conditions are met. For example, it can turn a light on, set the temperature on your thermostat or activate a scene. {% note %} -The difference between a condition and a trigger can be confusing as they are very similar. Triggers look at the actions, while conditions look at the current state: turning a light on versus a light being on. +The difference between a trigger and a condition can be confusing as they are very similar. + +Triggers require an event to happen for the conditions to be evaluated using current state information. + +Event: Arrive home \ +Condition: After Sunset? \ +Action: Turn lights on + {% endnote %} ## 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. **{% 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: +Automations 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 | | ---- | ----- | ---- | -| Entity ID | Unique identifier for the entity. | `light.kitchen` -| State | The current state of the device. | `home` +| Entity ID | Unique identifier for the entity. | `light.living_room` +| State | The current state of the device. | `off` | Attributes | Extra data related to the device and/or current state. | `brightness` State changes can be used as the source of triggers and the current state can be used in conditions. diff --git a/source/_docs/automation/templating.markdown b/source/_docs/automation/templating.markdown index 4132b0f3eabf..dd6de68240e5 100644 --- a/source/_docs/automation/templating.markdown +++ b/source/_docs/automation/templating.markdown @@ -48,7 +48,7 @@ These are the properties available for a [Calendar trigger](/docs/automation/tri ### Device -These are the properties available for a [Device trigger](/docs/automation/trigger/#device-trigger). +These are the properties available for a [Device trigger](/docs/automation/trigger/#device-triggers). Inherites template variables from [event](#event) or [state](#state) template based on the type of trigger selected for the device. diff --git a/source/_docs/automation/trigger.markdown b/source/_docs/automation/trigger.markdown index a51b2870e3ac..c26ec5882ab8 100644 --- a/source/_docs/automation/trigger.markdown +++ b/source/_docs/automation/trigger.markdown @@ -696,7 +696,7 @@ A string that represents a time to fire on each day. Can be specified as `HH:MM` automation: - triggers: - trigger: time - # Military time format. This trigger will fire at 3:32 PM + # 24-hour time format. This trigger will fire at 3:32 PM at: "15:32:00" ``` diff --git a/source/_docs/blueprint/schema.markdown b/source/_docs/blueprint/schema.markdown index 21df85fa3260..02b44b173cbb 100644 --- a/source/_docs/blueprint/schema.markdown +++ b/source/_docs/blueprint/schema.markdown @@ -134,6 +134,7 @@ The following example shows a minimal blueprint with a single input: blueprint: name: Example blueprint description: Example showing an input + domain: automation input: my_input: name: Example input diff --git a/source/_docs/blueprint/selectors.markdown b/source/_docs/blueprint/selectors.markdown index ea5d7f825037..4cfe13d1c35a 100644 --- a/source/_docs/blueprint/selectors.markdown +++ b/source/_docs/blueprint/selectors.markdown @@ -150,6 +150,12 @@ device: the set model. type: string required: false + model_id: + description: > + When set, the list of areas is limited to areas with devices that have + the set model ID. + type: string + required: false entity: description: > When entity options are provided, the list of areas is filtered by areas @@ -167,7 +173,7 @@ entity: required: false domain: description: > - Limits the list of areas that provide entities of a certain domain(s), + Limits the list of areas that provide entities of a certain [domain(s)](/docs/configuration/entities_domains/#domains), for example, [`light`](/integrations/light) or [`binary_sensor`](/integrations/binary_sensor). Can be either a string with a single domain, or a list of string domains to limit the selection to. @@ -485,7 +491,7 @@ devices based on the selector configuration. The value of the input will contain the device ID or a list of device IDs, based on if `multiple` is set to `true`. A device selector can filter the list of devices, based on things like the -manufacturer or model of the device, the entities the device provides or based +manufacturer, model, or model ID of the device, the entities the device provides or based on the domain that provided the device. ![Screenshot of a device selector](/images/blueprints/selector-device.png) @@ -515,7 +521,7 @@ entity: required: false domain: description: > - Limits the list of devices that provide entities of a certain domain(s), + Limits the list of devices that provide entities of a certain [domain(s)](/docs/configuration/entities_domains/#domains), for example, [`light`](/integrations/light) or [`binary_sensor`](/integrations/binary_sensor). Can be either a string with a single domain, or a list of string domains to limit the selection @@ -561,6 +567,11 @@ filter: When set, it limits the list of devices to devices that have the set model. type: string required: false + model_id: + description: > + When set, the list of devices is limited to devices that have the set model ID. + type: string + required: false multiple: description: > Allows selecting multiple devices. If set to `true`, the resulting value of @@ -683,7 +694,7 @@ filter: required: false domain: description: > - Limits the list of entities to entities of a certain domain(s), for example, + Limits the list of entities to entities of a certain [domain(s)](/docs/configuration/entities_domains/#domains), for example, [`light`](/integrations/light) or [`binary_sensor`](/integrations/binary_sensor). Can be either a string with a single domain, or a list of string domains to limit the selection @@ -792,6 +803,12 @@ device: the set model. type: string required: false + model_id: + description: > + When set, the list only includes floors with devices that have + the set model ID. + type: string + required: false entity: description: > When entity options are provided, the list only includes floors @@ -809,7 +826,7 @@ entity: required: false domain: description: > - When set, the list only includes floors that have entities of certain domains, + When set, the list only includes floors that have entities of certain [domains](/docs/configuration/entities_domains/#domains), for example, [`light`](/integrations/light) or [`binary_sensor`](/integrations/binary_sensor). Can be either a string with a single domain, or a list of string domains to limit the selection to. @@ -1342,6 +1359,10 @@ device: description: When set, it limits the targets to devices by the set model. type: string required: false + model_id: + description: When set, the targets are limited to devices that have the set model ID. + type: string + required: false entity: description: > When entity options are provided, the targets are limited by entities @@ -1359,7 +1380,7 @@ entity: required: false domain: description: > - Limits the targets to entities of a certain domain(s), + Limits the targets to entities of a certain [domain(s)](/docs/configuration/entities_domains/#domains), for example, [`light`](/integrations/light) or [`binary_sensor`](/integrations/binary_sensor). Can be either a with a single domain, or a list of string domains to limit the diff --git a/source/_docs/configuration/state_object.markdown b/source/_docs/configuration/state_object.markdown index c792feb5e35e..8b472c24ecfd 100644 --- a/source/_docs/configuration/state_object.markdown +++ b/source/_docs/configuration/state_object.markdown @@ -32,7 +32,7 @@ The `state` prefix indicates that this information is part of the state object ( ### About the state -The screenshot shows three lights in different states (the `state.state`): `on`, `off`, and `unavailable`. Each light comes with its own entity state attributes such as `supported_color_modes`, `supported_features`. These attributes have their own state: the state of the `supported_color_modes` attribute is `color_temp` and `hs`, the state of the `supported_features` attribute is `4`. +The screenshot of the Developer Tools States page shows three lights in different states (the `state.state`): `on`, `off`, and `unavailable`. Each light comes with its own entity state attributes such as `supported_color_modes`, `supported_features`. These attributes have their own state: the state of the `supported_color_modes` attribute is `color_temp` and `hs`, the state of the `supported_features` attribute is `4`.

Screenshot showing three lights with different states: `on`, `off`, or `unavailable` diff --git a/source/_docs/configuration/templating.markdown b/source/_docs/configuration/templating.markdown index 0ee7d7c73f19..323786ae9aea 100644 --- a/source/_docs/configuration/templating.markdown +++ b/source/_docs/configuration/templating.markdown @@ -427,6 +427,7 @@ The same thing can also be expressed as a test: - `device_attr(device_or_entity_id, attr_name)` returns the value of `attr_name` for the given device or entity ID. Can also be used as a filter. Not supported in [limited templates](#limited-templates). - `is_device_attr(device_or_entity_id, attr_name, attr_value)` returns whether the value of `attr_name` for the given device or entity ID matches `attr_value`. Can also be used as a test. Not supported in [limited templates](#limited-templates). - `device_id(entity_id)` returns the device ID for a given entity ID or device name. Can also be used as a filter. +- `device_name(lookup_value)` returns the device name for a given device ID or entity ID. Can also be used as a filter. #### Devices examples @@ -444,6 +445,11 @@ The same thing can also be expressed as a test: {{ device_id('sensor.sony') }} # deadbeefdeadbeefdeadbeefdeadbeef ``` +```text +{{ device_name('deadbeefdeadbeefdeadbeefdeadbeef') }} # Sony speaker +{{ device_name('sensor.sony') }} # Sony speaker +``` + {% endraw %} ### Config entries @@ -470,9 +476,10 @@ The same thing can also be expressed as a test: ### Floors - `floors()` returns the full list of floor IDs. -- `floor_id(lookup_value)` returns the floor ID for a given device ID, entity ID, area ID, or area name. Can also be used as a filter. +- `floor_id(lookup_value)` returns the floor ID for a given floor name or alias, area name or alias, entity ID or device ID. Can also be used as a filter. - `floor_name(lookup_value)` returns the floor name for a given device ID, entity ID, area ID, or floor ID. Can also be used as a filter. - `floor_areas(floor_name_or_id)` returns the list of area IDs tied to a given floor ID or name. Can also be used as a filter. +- `floor_entities(floor_name_or_id)` returns the list of entity IDs tied to a given floor ID or name. Can also be used as a filter. #### Floors examples @@ -486,6 +493,10 @@ The same thing can also be expressed as a test: {{ floor_id('First floor') }} # 'first_floor' ``` +```text +{{ floor_id('First floor alias') }} # 'first_floor' +``` + ```text {{ floor_id('my_device_id') }} # 'second_floor' ``` @@ -515,7 +526,7 @@ The same thing can also be expressed as a test: ### Areas - `areas()` returns the full list of area IDs -- `area_id(lookup_value)` returns the area ID for a given device ID, entity ID, or area name. Can also be used as a filter. +- `area_id(lookup_value)` returns the area ID for a given area name or alias, entity ID or device ID. Can also be used as a filter. - `area_name(lookup_value)` returns the area name for a given device ID, entity ID, or area ID. Can also be used as a filter. - `area_entities(area_name_or_id)` returns the list of entity IDs tied to a given area ID or name. Can also be used as a filter. - `area_devices(area_name_or_id)` returns the list of device IDs tied to a given area ID or name. Can also be used as a filter. @@ -532,6 +543,10 @@ The same thing can also be expressed as a test: {{ area_id('Living Room') }} # 'deadbeefdeadbeefdeadbeefdeadbeef' ``` +```text +{{ area_id('Living Room Alias') }} # 'deadbeefdeadbeefdeadbeefdeadbeef' +``` + ```text {{ area_id('my_device_id') }} # 'deadbeefdeadbeefdeadbeefdeadbeef' ``` @@ -726,7 +741,7 @@ For example, if you wanted to select a field from `trigger` in an automation bas - `utcnow()` returns a datetime object of the current time in the UTC timezone. - For specific values: `utcnow().second`, `utcnow().minute`, `utcnow().hour`, `utcnow().day`, `utcnow().month`, `utcnow().year`, `utcnow().weekday()` and `utcnow().isoweekday()`. - Using `utcnow()` will cause templates to be refreshed at the start of every new minute. -- `today_at(value)` converts a string containing a military time format to a datetime object with today's date in your time zone. Defaults to midnight (`00:00`). +- `today_at(value)` converts a string containing a 24-hour time format to a datetime object with today's date in your time zone. Defaults to midnight (`00:00`). - Using `today_at()` will cause templates to be refreshed at the start of every new minute. @@ -743,6 +758,8 @@ For example, if you wanted to select a field from `trigger` in an automation bas - `as_timestamp(value, default)` converts a datetime object or string to UNIX timestamp. If that fails, returns the `default` value, or if omitted raises an error. This function can also be used as a filter. - `as_local()` converts a datetime object to local time. This function can also be used as a filter. - `strptime(string, format, default)` parses a string based on a [format](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) and returns a datetime object. If that fails, it returns the `default` value or, if omitted, raises an error. +- `relative_time` converts a datetime object to its human-friendly "age" string. The age can be in seconds, minutes, hours, days, months, or years (but only the biggest unit is considered. For example, if it's 2 days and 3 hours, "2 days" will be returned). Note that it only works for dates _in the past_. + - Using `relative_time()` will cause templates to be refreshed at the start of every new minute. - `time_since(datetime, precision)` converts a datetime object into its human-readable time string. The time string can be in seconds, minutes, hours, days, months, and years. `precision` takes an integer (full number) and indicates the number of units returned. The last unit is rounded. For example: `precision = 1` could return "2 years" while `precision = 2` could return "1 year 11 months". This function can also be used as a filter. If the datetime is in the future, returns 0 seconds. A precision of 0 returns all available units, default is 1. @@ -1173,6 +1190,31 @@ Some examples: +### Hashing + +The template engine contains a few filters and functions to hash a string of +data. A few very common hashing algorithms are supported: `md5`, `sha1`, +`sha256`, and `sha512`. + +Some examples: + +{% raw %} + +- `{{ md5("Home Assistant") }}` - renders as `f3f2b8b3b40084aa87e92b7ffb02ed13885fea2d07` +- `{{ "Home Assistant" | md5 }}` - renders as `f3f2b8b3b40084aa87e92b7ffb02ed13885fea2d07` + +- `{{ sha1("Home Assistant") }}` - renders as `14bffd017c73917bfda2372aaf287570597b8e82` +- `{{ "Home Assistant" | sha1 }}` - renders as `14bffd017c73917bfda2372aaf287570597b8e82` + +- `{{ sha256("Home Assistant") }}` - renders as `a18f473c9d3ed968a598f996dcf0b9de84de4ee04c950d041b61297a25bcea49` +- `{{ "Home Assistant" | sha256 }}` - renders as `a18f473c9d3ed968a598f996dcf0b9de84de4ee04c950d041b61297a25bcea49` + +- `{{ sha512("Home Assistant") }}` - renders as `f251e06eb7d3439e1a86d6497d6a4531c3e8c809f538be62f89babf147d7d63aca4e77ae475b94c654fd38d8f543f778ce80007d6afef379d8a0e5d3ddf7349d` +- `{{ "Home Assistant" | sha512 }}` - renders as `f251e06eb7d3439e1a86d6497d6a4531c3e8c809f538be62f89babf147d7d63aca4e77ae475b94c654fd38d8f543f778ce80007d6afef379d8a0e5d3ddf7349d` + +{% endraw %} + + ### Regular expressions For more information on regular expressions @@ -1184,6 +1226,137 @@ See: [Python regular expression operations](https://docs.python.org/3/library/re - Filter `value | regex_findall(find='', ignorecase=False)` will find all regex matches of the find expression in `value` and return the array of matches. - Filter `value | regex_findall_index(find='', index=0, ignorecase=False)` will do the same as `regex_findall` and return the match at index. +### Shuffling + +The template engine contains a filter and function to shuffle a list. + +Shuffling can happen randomly or reproducibly using a seed. When using a seed +it will always return the same shuffled list for the same seed. + +Some examples: + +{% raw %} + +- `{{ [1, 2, 3] | shuffle }}` - renders as `[3, 1, 2]` (_random_) +- `{{ shuffle([1, 2, 3]) }}` - renders as `[3, 1, 2]` (_random_) +- `{{ shuffle(1, 2, 3) }}` - renders as `[3, 1, 2]` (_random_) + +- `{{ [1, 2, 3] | shuffle("random seed") }}` - renders as `[2, 3, 1] (_reproducible_) +- `{{ shuffle([1, 2, 3], seed="random seed") }}` - renders as `[2, 3, 1] (_reproducible_) +- `{{ shuffle([1, 2, 3], "random seed") }}`- renders as `[2, 3, 1] (_reproducible_) +- `{{ shuffle(1, 2, 3, seed="random seed") }}` - renders as `[2, 3, 1] (_reproducible_) + +{% endraw %} + +### Flatten a list of lists + +The template engine provides a filter to flatten a list of lists: `flatten`. + +It will take a list of lists and return a single list with all the elements. +The depth of the flattening can be controlled using the `levels` parameter. +The flattening process is recursive, so it will flatten all nested lists, until +the number of levels (if specified) is reached. + +Some examples: + +{% raw %} + +- `{{ flatten([1, [2, [3]], 4, [5 , 6]]) }}` - renders as `[1, 2, 3, 4, 5, 6]` +- `{{ [1, [2, [3]], 4, [5 , 6]] | flatten }}` - renders as `[1, 2, 3, 4, 5, 6]` + +- `{{ flatten([1, [2, [3]]], levels=1) }}` - renders as `[1, 2, [3]]` +- `{{ [1, [2, [3]]], flatten(levels=1) }}` - renders as `[1, 2, [3]]` + +- `{{ flatten([1, [2, [3]]], 1) }}` - renders as `[1, 2, [3]]` +- `{{ [1, [2, [3]]], flatten(1) }}` - renders as `[1, 2, [3]]` + +{% endraw %} + +### Find common elements between lists + +The template engine provides a filter to find common elements between two lists: `intersect`. + +This function returns a list containing all elements that are present in both input lists. + +Some examples: + +{% raw %} + +- `{{ intersect([1, 2, 5, 3, 4, 10], [1, 2, 3, 4, 5, 11, 99]) }}` - renders as `[1, 2, 3, 4, 5]` +- `{{ [1, 2, 5, 3, 4, 10] | intersect([1, 2, 3, 4, 5, 11, 99]) }}` - renders as `[1, 2, 3, 4, 5]` +- `{{ intersect(['a', 'b', 'c'], ['b', 'c', 'd']) }}` - renders as `['b', 'c']` +- `{{ ['a', 'b', 'c'] | intersect(['b', 'c', 'd']) }}` - renders as `['b', 'c']` + +{% endraw %} + +### Find elements in first list not in second list + +The template engine provides a filter to find elements that are in the first list but not in the second list: `difference`. +This function returns a list containing all elements that are present in the first list but absent from the second list. + +Some examples: + +{% raw %} + +- `{{ difference([1, 2, 5, 3, 4, 10], [1, 2, 3, 4, 5, 11, 99]) }}` - renders as `[10]` +- `{{ [1, 2, 5, 3, 4, 10] | difference([1, 2, 3, 4, 5, 11, 99]) }}` - renders as `[10]` +- `{{ difference(['a', 'b', 'c'], ['b', 'c', 'd']) }}` - renders as `['a']` +- `{{ ['a', 'b', 'c'] | difference(['b', 'c', 'd']) }}` - renders as `['a']` + +{% endraw %} + +### Find elements that are in either list but not in both + +The template engine provides a filter to find elements that are in either of the input lists but not in both: `symmetric_difference`. +This function returns a list containing all elements that are present in either the first list or the second list, but not in both. + +Some examples: + +{% raw %} + +- `{{ symmetric_difference([1, 2, 5, 3, 4, 10], [1, 2, 3, 4, 5, 11, 99]) }}` - renders as `[10, 11, 99]` +- `{{ [1, 2, 5, 3, 4, 10] | symmetric_difference([1, 2, 3, 4, 5, 11, 99]) }}` - renders as `[10, 11, 99]` +- `{{ symmetric_difference(['a', 'b', 'c'], ['b', 'c', 'd']) }}` - renders as `['a', 'd']` +- `{{ ['a', 'b', 'c'] | symmetric_difference(['b', 'c', 'd']) }}` - renders as `['a', 'd']` + +{% endraw %} + +### Combine all unique elements from two lists + +The template engine provides a filter to combine all unique elements from two lists: `union`. +This function returns a list containing all unique elements that are present in either the first list or the second list. + +Some examples: + +{% raw %} + +- `{{ union([1, 2, 5, 3, 4, 10], [1, 2, 3, 4, 5, 11, 99]) }}` - renders as `[1, 2, 3, 4, 5, 10, 11, 99]` +- `{{ [1, 2, 5, 3, 4, 10] | union([1, 2, 3, 4, 5, 11, 99]) }}` - renders as `[1, 2, 3, 4, 5, 10, 11, 99]` +- `{{ union(['a', 'b', 'c'], ['b', 'c', 'd']) }}` - renders as `['a', 'b', 'c', 'd']` +- `{{ ['a', 'b', 'c'] | union(['b', 'c', 'd']) }}` - renders as `['a', 'b', 'c', 'd']` + +{% endraw %} + +### Combining dictionaries + +The template engine provides a function and filter to merge multiple dictionaries: `combine`. + +It will take multiple dictionaries and merge them into a single dictionary. When used as a filter, +the filter value is used as the first dictionary. The optional `recursive` parameter determines +whether nested dictionaries should be merged (defaults to `False`). + +Some examples: + +{% raw %} + +- `{{ {'a': 1, 'b': 2} | combine({'b': 3, 'c': 4}) }}` - renders as `{'a': 1, 'b': 3, 'c': 4}` +- `{{ combine({'a': 1, 'b': 2}, {'b': 3, 'c': 4}) }}` - renders as `{'a': 1, 'b': 3, 'c': 4}` + +- `{{ combine({'a': 1, 'b': {'x': 1}}, {'b': {'y': 2}, 'c': 4}, recursive=True) }}` - renders as `{'a': 1, 'b': {'x': 1, 'y': 2}, 'c': 4}` +- `{{ combine({'a': 1, 'b': {'x': 1}}, {'b': {'y': 2}, 'c': 4}) }}` - renders as `{'a': 1, 'b': {'y': 2}, 'c': 4}` + +{% endraw %} + ## Merge action responses Using action responses we can collect information from various entities at the same time. @@ -1479,11 +1652,13 @@ Example value template: With given payload: ```json -{ "state": "ON", "temperature": 21.902 } +{ "state": "ON", "temperature": 21.902, "humidity": null } ``` Template {% raw %}`{{ value_json.temperature | round(1) }}`{% endraw %} renders to `21.9`. +Template {% raw %}`{{ value_json.humidity }}`{% endraw %} renders to `None`. + {% endnote %} #### Using command templates with MQTT @@ -1514,6 +1689,44 @@ When a command template renders to a valid `bytes` literal, then MQTT will publi - Template {% raw %}`{{ 16 }}`{% endraw %} renders to payload encoded string `"16"`. - Template {% raw %}`{{ pack(0x10, ">B") }}`{% endraw %} renders to a raw 1 byte payload `0x10`. +### Determining types + +When working with templates, it can be useful to determine the type of +the returned value from a method or the type of a variable at times. + +For this, Home Assistant provides the `typeof()` template function and filter, +which is inspired by the [JavaScript](https://en.wikipedia.org/wiki/JavaScript) +`typeof` operator. It reveals the type of the given value. + +This is mostly useful when you are debugging or playing with templates in +the developer tools of Home Assistant. However, it might be useful in some +other cases as well. + +Some examples: + +{% raw %} + +- `{{ typeof(42) }}` - renders as `int` +- `{{ typeof(42.0) }}` - renders as `float` +- `{{ typeof("42") }}` - renders as `str` +- `{{ typeof([1, 2, 3]) }}` - renders as `list` +- `{{ typeof({"key": "value"}) }}` - renders as `dict` +- `{{ typeof(True) }}` - renders as `bool` +- `{{ typeof(None) }}` - renders as `NoneType` + +- `{{ 42 | typeof }}` - renders as `int` +- `{{ 42.0 | typeof }}` - renders as `float` +- `{{ "42" | typeof }}` - renders as `str` +- `{{ [1, 2, 3] | typeof }}` - renders as `list` +- `{{ {"key": "value"} | typeof }}` - renders as `dict` +- `{{ True | typeof }}` - renders as `bool` +- `{{ None | typeof }}` - renders as `NoneType` + +- `{{ some_variable | typeof }}` - renders the type of `some_variable` +- `{{ states("sensor.living_room") | typeof }}` - renders the type of the result of `states()` function + +{% endraw %} + ## Some more things to keep in mind ### `entity_id` that begins with a number diff --git a/source/_docs/energy/individual-devices.markdown b/source/_docs/energy/individual-devices.markdown index ec6222a18c22..9a2c734ee24b 100644 --- a/source/_docs/energy/individual-devices.markdown +++ b/source/_docs/energy/individual-devices.markdown @@ -22,3 +22,19 @@ Smart relays sit behind your "normal" switches and make them smart. It allows yo Some smart devices, such as air conditioning, boilers, and others, may provide a power sensor, measured in Watts. You can use the [Integration (Riemann sum integral) integration](/integrations/integration/#energy) to calculate the energy your device is using. You can then use the energy sensor in the Energy Dashboard, as individual devices. For information on setting up an entity for use in the **Energy** dashboard, refer to the [energy FAQ](/docs/energy/faq/#troubleshooting-missing-entities). Graphic showing energy flowing from the home to individual devices. + +## Upstream devices and hierarchies + +You can create a hierarchy of devices by setting one device as an "upstream device" of another. This means you can now establish parent-child relationships between devices within your energy configuration. + +For example, imagine having a breaker monitoring the total energy consumption of a circuit, but also separately tracking individual devices connected to that circuit. Without setting the device hierarchies, Home Assistant might double-count this usage. By setting the hierarchy, it understands these relationships and accurately shows the individual device usage without duplication. +To set up an upstream device relationship: + +1. Add an energy consumption entity as an individual device. +2. Then, when configuring other individual devices, you can select the previously added individual entity as their upstream device. + +This hierarchical view helps you understand which devices are consuming power from which sources and prevents energy from being counted multiple times. + +{% important %} +To set up a hierarchy, you must first add all related entities as individual devices in the energy dashboard. Only devices that are already listed under individual devices can be selected as "upstream device" for other devices. +{% endimportant %} diff --git a/source/_docs/energy/water.markdown b/source/_docs/energy/water.markdown index e26f36e6519a..8dfb726ee1b8 100644 --- a/source/_docs/energy/water.markdown +++ b/source/_docs/energy/water.markdown @@ -65,6 +65,8 @@ Maybe you like to build one yourself? - [watermeter](https://github.com/nohn/watermeter) running classic OCR and statistical pattern recognition on any system supporting Docker - [Muino water meter reader 3-phase](https://muino.nl/product/3-phase-muino-light-sensor-encoder/) Using the 3-phase sensor technique, a battery-powered version can be possible with this sensor. - [Read water meter with magnetometer](https://github.com/tronikos/esphome-magnetometer-water-gas-meter) using [QMC5883L](https://esphome.io/components/sensor/qmc5883l.html) or [HMC5883L](https://esphome.io/components/sensor/hmc5883l.html), common and inexpensive magnetometers. This should be compatible with all the water meters the Flume water sensor is compatible with, which is [compatible](https://help.flumewater.com/en/articles/1618594-is-the-flume-device-compatible-with-all-water-meters) with about 95% of water meters in the United States. +- Some watermeters use [Wireless M-Bus](https://en.wikipedia.org/wiki/Meter-Bus) for remote metering. [wmbusmeters project](https://github.com/wmbusmeters/wmbusmeters/) can automatically capture, decode, decrypt and convert M-Bus packets to MQTT. It supports several M-Bus receivers, including RTL-SDR using [rtl-wmbus library](https://github.com/xaelsouth/rtl-wmbus). You can also build a WMBus [ESPHome-based receiver](https://github.com/SzczepanLeon/esphome-components). An [add-on](https://github.com/wmbusmeters/wmbusmeters-ha-addon) for Home Assistant exists for easy installation and configuration. See the [community page](https://community.home-assistant.io/t/add-on-request-wmbusmeter/228988) for more. +- Read water (or gas) usage data from the Itron EverBlu Cyble Enhanced RF meters using the RADIAN protocol over 433 MHz [everblu-meters-esp8266/esp32](https://github.com/genestealer/everblu-meters-esp8266-improved), via an ESP32/ESP8266 and a CC1101 transceiver. Used across the UK and Europe. Fully integrates with Home Assistant using MQTT AutoDiscovery. According to available documentation, this method may also work with AnyQuest Cyble Enhanced, EverBlu Cyble, and AnyQuest Cyble Basic, but these remain untested. If you manually integrate your sensors, for example, using the [MQTT](/integrations/mqtt) or [RESTful](/integrations/rest) integrations: Make sure you set and provide the `device_class`, `state_class`, and `unit_of_measurement` for those sensors. diff --git a/source/_docs/organizing/areas.markdown b/source/_docs/organizing/areas.markdown index 93eebe783232..e91254d58928 100644 --- a/source/_docs/organizing/areas.markdown +++ b/source/_docs/organizing/areas.markdown @@ -11,12 +11,14 @@ related: title: Categories - docs: /docs/configuration/templating/#areas title: Using areas in template + - docs: /dashboards/dashboards/#areas-dashboard + title: Areas dashboard --- An area in Home Assistant is a logical grouping of {% term devices %} and {% term entities %} that are meant to match areas (or rooms) in the physical world of your home. For example, the "Living room" area groups devices and entities in your living room. Areas allow you to target an entire group of devices with an action. For example, turning off all the lights in the living room. -Areas can be assigned to floors. Areas can also be used to automatically generate cards, such as the [Area card](/dashboards/area/). +Areas can be assigned to {% term floors %}. Areas can also be used to automatically generate cards, such as the [Area card](/dashboards/area/). ## Creating an area @@ -27,7 +29,7 @@ Follow these steps to create a new area from the **Areas** view. - Give the area a **Name** (required). - Add an icon (We use [Material icons](https://pictogrammers.com/library/mdi/)). - Assign the area to a floor. - - If you have not created floors yet, you can [create a new one](/docs/organizing/floors/#creating-a-floor). + - If you have not created floors yet, you can [create a new floor](/docs/organizing/floors/#creating-a-floor). - The number can be negative. For example for underground floors. - This number can later be used for sorting. - Add an image representing that area. @@ -41,15 +43,15 @@ Follow these steps to create a new area from the **Areas** view. ## Assigning areas to floors and add labels -If an area has not yet been assigned to a floor, it is shown in the **Unassigned areas** section. Follow these steps to assign an area to a floor. +If an area has not yet been assigned to a {% term floor %}, it is shown in the **Unassigned areas** section. Follow these steps to assign an area to a floor. 1. Go to {% my areas title="**Settings** > **Areas, labels & zones**" %} and select **Create area**. 2. On the area card, select the edit {% icon "mdi:edit" %} button. -3. In the dialog, select the floor and add labels, if you like. +3. In the dialog, select the {% term floor %} and add {% term labels %} if you like. ## Assigning an area to multiple items -You can assign an area to multiple items at once in the automation, scene, script, and device pages. +You can assign an area to multiple items at once in the {% term automation %}, {% term scene %}, {% term script %}, and {% term device %} pages. 1. Depending on what you want to assign, go to one of the following pages: - For automations, scripts, or scenes {% my automations title="**Settings** > **Automations & Scenes**" %} and open the respective tab. @@ -76,6 +78,15 @@ Follow these steps to edit an area. - Add an **Alias**. - Aliases are alternative names used in [voice assistants](/voice_control/aliases/) to refer to an area, entity, or floor. +## Using the Areas dashboard + +Once you have assigned your entities to areas, you can use the **Areas** dashboard. The **Areas** dashboard is a pre-populated dashboard that shows your {% term entities %} grouped by areas. To learn how, refer to the documentation on the [Areas dashboard](/dashboards/dashboards/#areas-dashboard). + +

+Screenshot of the Areas default dashboard +Screenshot of the Areas default dashboard. +

+ ## Deleting an area Follow these steps to delete an area. It will be removed from all the floors it was assigned to. All the devices that were assigned to this area will become unassigned. diff --git a/source/_docs/organizing/floors.markdown b/source/_docs/organizing/floors.markdown index bb62473b88b8..55106127a546 100644 --- a/source/_docs/organizing/floors.markdown +++ b/source/_docs/organizing/floors.markdown @@ -13,9 +13,9 @@ related: title: Using floor alias for voice assistants --- -A floor in Home Assistant is a logical grouping of areas meant to match your home's physical floors. +A floor in Home Assistant is a logical grouping of {% term areas %} meant to match your home's physical floors. -Devices and entities cannot be assigned to floors directly but to areas. Floors can be used in automations and scripts as a target for actions. For example, to turn off all the lights on the downstairs floor when you go to bed. +Devices and entities cannot be assigned to floors directly but to areas. Floors can be used in {% term automations %} and {% term scripts %} as a target for {% term actions %}. For example, to turn off all the lights on the downstairs floor when you go to bed. ## Creating a floor @@ -41,11 +41,11 @@ Follow these steps to create a new floor. ## Deleting a floor -Follow these steps to delete a floor. Areas that are assigned to a floor will become unassigned. Automations and scripts or voice assistants that used a floor as a target will no longer work as they no longer have a target. +Follow these steps to delete a floor. Areas that are assigned to a floor will become unassigned. {% term Automations %} and {% term scripts %} or voice assistants that used a floor as a target will no longer work as they no longer have a target. 1. Go to {% my areas title="**Settings** > **Areas, labels & zones**" %}. 2. Next to the floor, select the three dots {% icon "mdi:dots-vertical" %} menu and select **Delete floor**. ![Screenshot showing the dialog to delete a floor](/images/organizing/floor_delete.png) -3. If you have automations, scripts, or voice assistants that used floors as a target, you will need to update these. +3. If you have {% term automations %}, {% term scripts %}, or voice assistants that used floors as a target, you will need to update these. diff --git a/source/_docs/scripts.markdown b/source/_docs/scripts.markdown index f6634872d2c9..43727ded7df3 100644 --- a/source/_docs/scripts.markdown +++ b/source/_docs/scripts.markdown @@ -62,7 +62,7 @@ The variables {% term action %} allows you to set/override variables that will b ```yaml - alias: "Set variables" variables: - entities: + entities: - light.kitchen - light.living_room brightness: 100 @@ -94,9 +94,7 @@ Variables can be templated. ### Scope of variables -Variables defined by the `variables` {% term action %} have local scope. This means that if a variable is changed in a nested sequence block, that change will not be visible in an outer sequence block. - -Inside the `if` sequence the `variables` {% term action %} will only alter the `people` variable for that sequence. +The `variables` {% term action %} assigns the values to previously defined variables with the same name. If a variable was not previously defined, it is assigned in the top-level (script run) scope. {% raw %} @@ -111,17 +109,17 @@ sequence: entity_id: device_tracker.paulus state: "home" then: - # At this scope and this point of the sequence, people == 0 - variables: people: "{{ people + 1 }}" - # At this scope, people will now be 1 ... + paulus_home: true - action: notify.notify data: message: "There are {{ people }} people home" # "There are 1 people home" - # ... but at this scope it will still be 0 + # Variable value is now updated - action: notify.notify data: - message: "There are {{ people }} people home" # "There are 0 people home" + message: "There are {{ people }} people home {% if paulus_home is defined %}(including Paulus){% endif %}" + # "There are 1 people home (including Paulus)" ``` {% endraw %} @@ -213,8 +211,8 @@ This {% term action %} evaluates the template, and if true, the script will cont The template is re-evaluated whenever an entity ID that it references changes state. If you use non-deterministic functions like `now()` in the template it will not be continuously re-evaluated, but only when an entity ID that is referenced is changed. If you need to periodically re-evaluate the template, reference a sensor from the [Time and Date](/integrations/time_date/) integration that will update minutely or daily. {% raw %} -```yaml +```yaml # Wait until media player is stopped - alias: "Wait until media player is stopped" wait_template: "{{ is_state('media_player.floor', 'stop') }}" @@ -258,8 +256,8 @@ With both types of waits it is possible to set a timeout after which the script You can also get the script to abort after the timeout by using optional `continue_on_timeout: false`. {% raw %} -```yaml +```yaml # Wait for IFTTT event or abort after specified timeout. - wait_for_trigger: - trigger: event @@ -322,6 +320,7 @@ This can be used to take different actions based on whether or not the condition target: entity_id: switch.some_light ``` + {% endraw %} ## Fire an event @@ -453,7 +452,7 @@ repeat: {% endraw %} Other types are accepted as list items, for example, each item can be a -template, or even an mapping of key/value pairs. +template, or even an mapping of key/value pairs. {% raw %} @@ -509,7 +508,7 @@ For example: - repeat: while: "{{ is_state('sensor.mode', 'Home') and repeat.index < 10 }}" sequence: - - ... + - ... ``` {% endraw %} @@ -559,8 +558,9 @@ For example: - repeat: until: "{{ is_state('device_tracker.iphone', 'home') }}" sequence: - - ... + - ... ``` + {% endraw %} ### Repeat loop variable @@ -691,7 +691,6 @@ automation: {% endraw %} - More `choose` can be used together. This is the case of an IF-IF. The following example shows how a single {% term automation %} can control entities that aren't related to each other but have in common the same trigger. @@ -856,10 +855,8 @@ Some of the caveats of running {% term actions %} in parallel: there is no guarantee that they will be completed in the same order. - If one {% term action %} fails or errors, the other {% term actions %} will keep running until they too have finished or errored. -- Variables created/modified in one parallelized {% term action %} are not available - in another parallelized {% term action %}. Each step in a parallelized has its own scope. -- The response data of a parallelized {% term action %} is however also available outside of its - own scope. This is especially useful for parallelizing execution of long-running {% term actions %}. +- Variables created/modified in one parallelized {% term action %} can conflict with variables + from another parallelized {% term action %}. Make sure to give them distinct names to prevent that. ## Stopping a script sequence @@ -963,7 +960,7 @@ blueprint: input: input_boolean: name: Boolean - selector: + selector: boolean: actions: diff --git a/source/_docs/scripts/perform-actions.markdown b/source/_docs/scripts/perform-actions.markdown index ce1120cdd5e5..e83c6f6910a7 100644 --- a/source/_docs/scripts/perform-actions.markdown +++ b/source/_docs/scripts/perform-actions.markdown @@ -5,7 +5,7 @@ description: "Instructions on how to perform actions in Home Assistant." Various integrations allow performing {% term actions %} when a certain event occurs. The most common one is performing an action when an automation {% term trigger %} happens. But an action can also be called from a {% term script %}, a dashboard, or via voice command devices such as Amazon Echo. -The configuration options to call a configuration are the same between all integrations and are described on this page. +The configuration options to perform action are the same between all integrations and are described on this page. Examples on this page will be given as part of an automation integration configuration but different approaches can be used for other integrations too. diff --git a/source/_docs/z-wave/controllers.markdown b/source/_docs/z-wave/controllers.markdown index bb21087bc5b2..2f331de65a8f 100644 --- a/source/_docs/z-wave/controllers.markdown +++ b/source/_docs/z-wave/controllers.markdown @@ -12,13 +12,14 @@ You need to have a compatible Z-Wave stick or module installed. The following de The firmwares of 700 and 800 series Z-Wave controllers have several bugs which impact the stability of the mesh and can cause the controller to become unresponsive. Because there is no known firmware version that is completely fixed, it is recommended to choose a firmware based on the following criteria: - 700 series: - - prefer SDK versions 7.17.2 to 7.18.x + - prefer SDK versions 7.17.2 to 7.18.x or 7.21.6 and newer - SDK versions 7.19.x are okay - avoid SDK versions before 7.17.2 - - avoid SDK versions 7.20 to 7.21.3 + - avoid SDK versions 7.20 to 7.21.5 - 800 series - - prefer SDK versions 7.22.x + - prefer SDK versions 7.23.x and newer + - SDK versions 7.22.x are okay - SDK versions 7.17.2 to 7.19.x are okay - avoid SDK versions before 7.17.2 - avoid SDK versions 7.20 to 7.21.3 @@ -58,7 +59,7 @@ Firmware can be upgraded using the below directions: - GoControl HUSBZB-1 stick - Sigma Designs UZB stick - Vision USB stick - Gen5 - - Z-Wave.Me UZB1 stick + - Z-Wave.Me UZB1 stick (see Aeotec Z-Stick note below) - HomeSeer SmartStick+ G2 - HomeSeer Z-NET G2 @@ -93,7 +94,9 @@ Z-Wave JS does not support Z-Wave Long Range yet. ### Aeotec Z-Stick {% note %} -There are [known compatibility issues](https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=245031#p1502030) with older hardware versions of the Aeotec stick not connecting when plugged directly on the Raspberry Pi 4, and requiring a USB Hub to work. Aeotec has released a 2020 hardware revision ZW090-A/B/C Gen5+ with Pi 4 compatibility. Both hardware revisions are still being sold, make informed purchasing decisions if using one paired with a Pi 4. + +The Aeotec Z-Stick and some of its variants (e.g. Z-Wave.Me UZB1) are known to have compatibility issues with the Linux kernel because of their [non-compliant behavior](https://forums.raspberrypi.com/viewtopic.php?f=28&t=245031#p1502030). Plugging these controllers through a USB hub can serve as a workaround that sometimes mitigates the issue. + {% endnote %} It's totally normal for your Z-Wave stick to cycle through its LEDs (Yellow, Blue and Red) while plugged into your system. diff --git a/source/_includes/asides/component_navigation.html b/source/_includes/asides/component_navigation.html index b9af18dbe207..0f2198ebdcbe 100644 --- a/source/_includes/asides/component_navigation.html +++ b/source/_includes/asides/component_navigation.html @@ -55,9 +55,9 @@  Its IoT class is {{ page.ha_iot_class }}. {%- endif -%} - + {%- if page.ha_quality_scale %} -
+
{% if page.ha_quality_scale == "bronze" %}🥉 Bronze quality
{%- endif -%} {% if page.ha_quality_scale == "silver" %}🥈 Silver quality
{%- endif -%} {% if page.ha_quality_scale == "gold" %}🥇 Gold quality
{%- endif -%} @@ -67,12 +67,12 @@ {% if page.ha_quality_scale == "custom" %}📦 Custom integration
{%- endif -%}
{%- endif -%} - + {% if page.works_with %} {%- for type in page.works_with -%} {%- endfor -%} @@ -96,7 +96,7 @@

{% icon "mdi:person-heart" %} Integration owners

{% assign ha_project = true %} {% endif %} {% endfor %} - + {% if ha_project %}
This integration is being maintained by the Home Assistant project. diff --git a/source/_includes/asides/dashboards_navigation.html b/source/_includes/asides/dashboards_navigation.html index 6e4340a4e7ec..f204d9496ac5 100644 --- a/source/_includes/asides/dashboards_navigation.html +++ b/source/_includes/asides/dashboards_navigation.html @@ -5,7 +5,7 @@

Dashboards