From af26c20de56d7904056b909ca10b690186f79511 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Fri, 19 Jan 2024 16:57:06 +0100 Subject: [PATCH] Add icon translations documentation (#2047) Co-authored-by: Joost Lekkerkerker --- blog/2024-01-19-icon-translations.md | 37 +++++++++++++ docs/core/entity.md | 83 +++++++++++++++++++++++++++- 2 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 blog/2024-01-19-icon-translations.md diff --git a/blog/2024-01-19-icon-translations.md b/blog/2024-01-19-icon-translations.md new file mode 100644 index 00000000..b8678c48 --- /dev/null +++ b/blog/2024-01-19-icon-translations.md @@ -0,0 +1,37 @@ +--- +author: Franck Nijhof +authorURL: https://twitter.com/frenck +authorImageURL: /img/profile/frenck.png +authorTwitter: frenck +title: Icon translations +--- + +In Home Assistant 2024.2, we will introduce a new way to provide icons for integrations: Icon translations. + +Icon translations work similarly to our regular translations for entities, which can translate the state of an entity or entity attribute state into any language. Icon translations work in a similar way, but instead of translating the state into the end-user language, it translates the state into an icon. + +Each integration can now provide an `icons.json` file, containing a mapping of states to icons. Here is an example of a Moon `sensor` entity that provides different icons for each state: + +```json +{ + "entity": { + "sensor": { + "phase": { + "default": "mdi:moon", + "state": { + "new_moon": "mdi:moon-new", + "first_quarter": "mdi:moon-first-quarter", + "full_moon": "mdi:moon-full", + "last_quarter": "mdi:moon-last-quarter" + } + } + } + } +} +``` + +Icon translations also support translating entity attribute states. + +[Read more about icon translations in our documentation](/docs/core/entity#icons). + +This change is backward-compatible. The existing `icon` property of entities will continue to work as it did before. However, we recommend the use of the icon translation over the `icon` property. diff --git a/docs/core/entity.md b/docs/core/entity.md index f23a98a8..78bb346c 100644 --- a/docs/core/entity.md +++ b/docs/core/entity.md @@ -82,7 +82,7 @@ To avoid calculations in a property method, set the corresponding [entity class | should_poll | `bool` | `True` | Should Home Assistant check with the entity for an updated state. If set to `False`, entity will need to notify Home Assistant of new updates by calling one of the [schedule update methods](integration_fetching_data.md#push-vs-poll). | state | str | int | float | None | `None` | The state of the entity. In most cases this is implemented by the domain base entity and should not be implemented by integrations. | supported_features | int | None | `None` | Flag features supported by the entity. Domains specify their own. -| translation_key | str | None | `None` | A key for looking up translations of the entity's state in [`entity` section of the integration's `strings.json`](/docs/internationalization/core#state-of-entities). +| translation_key | str | None | `None` | A key for looking up translations of the entity's state in [`entity` section of the integration's `strings.json`](/docs/internationalization/core#state-of-entities) and for translating the state into an matching [icon](#icons). | | translation_placeholders | dict | None | `None` | Placeholder definitions for [translated entity name](/docs/internationalization/core/#name-of-entities). :::warning @@ -115,7 +115,7 @@ The following properties are also available on entities. However, they are for a | ------------------------------- | ---------------------------- | ------- | ----------- | capability_attributes | dict | None | `None` | State attributes which are stored in the entity registry. This property is implemented by the domain base entity and should not be implemented by integrations. | force_update | `bool` | `False` | Write each update to the state machine, even if the data is the same. Example use: when you are directly reading the value from a connected sensor instead of a cache. Use with caution, will spam the state machine. | -| icon | str | None | `None` | Icon to use in the frontend. Icons start with `mdi:` plus an [identifier](https://materialdesignicons.com/). You probably don't need this since Home Assistant already provides default icons for all entities according to its `device_class`. This should be used only in the case where there either is no matching `device_class` or where the icon used for the `device_class` would be confusing or misleading. | +| icon | str | None | `None` | Icon to use in the frontend. Using this property is no recommended. [More information about using icons](#icons). | | state_attributes | dict | None | `None` | State attributes of a base domain. This property is implemented by the domain base entity and should not be implemented by integrations. | unit_of_measurement | str | None | The unit of measurement that the entity's state is expressed in. In most cases, for example for the `number` and `sensor` domains, this is implemented by the domain base entity and should not be implemented by integrations. @@ -376,6 +376,85 @@ Called when an entity has their entity_id and hass object assigned, before it is Called when an entity is about to be removed from Home Assistant. Example use: disconnect from the server or unsubscribe from updates. +## Icons + +Every entity in Home Assistant has an icon, which is used as a visual indicator to identify the entity more easily in the frontend. Home Assistant uses the [Material Design Icons](https://materialdesignicons.com/) icon set. + +In most cases, Home Assistant will pick an icon automatically based on the entity's domain, `device_class`, and `state`. It is preferred to use the default icon if possible, to provide a consistent experience and to avoid confusion for the user. However, it is possible to override provide a custom icon for an entity. + +Regardless of the provided icon, it is always possible for the user to customize the icon to their liking in the frontend. + +There are two ways to provide a custom icon for an entity, either by providing icon translations or by providing an icon identifier. + +### Icon translations + +This is the preferred and most modern way to provide a custom icon for an entity. Icon translations work similarly [our regular translations](/docs/internationalization/core#state-of-entities), but instead of translating the state of an entity, they translate the states of an entity to icons. + +The `translation_key` property of an entity defines the icon translation to use. This property is used to look up the translation in the `entity` section of the integration's `icons.json` file. + +To differentiate entities and their translations, provide different translation keys. The following example `icons` for a Moon domain `sensor` entity with its `translation_key` property set to phase: + +```json +{ + "entity": { + "sensor": { + "phase": { + "default": "mdi:moon", + "state": { + "new_moon": "mdi:moon-new", + "first_quarter": "mdi:moon-first-quarter", + "full_moon": "mdi:moon-full", + "last_quarter": "mdi:moon-last-quarter" + } + } + } + } +} +``` + +Notice that icons start with `mdi:` plus an [identifier](https://materialdesignicons.com/). The `default` icon is used when the entity's state is not in the `state` section. The `state` section is optional, and if not provided, the `default` icon will be used for all states. + +Icons for entity state attributes can also be provided. The following example provides icons for a `climate` entity with its `translation_key` property set to `ubercool`. This entity has a `preset_mode` state attribute, which can be set to `vacation` or `night`. The frontend will use these in, for example, the climate card. + +```json +{ + "entity": { + "climate": { + "ubercool": { + "state_attributes": { + "preset_mode": { + "default": "mdi:confused", + "state": { + "vacation": "mdi:umbrella-beach", + "night": "mdi:weather-night" + } + } + } + } + } + } +} +``` + +### Icon property + +Another way to provide an icon for an entity is by setting the `icon` property of an entity, which returns a string referencing the `mdi` icon. As this property is a method, it is possible to return different icons based on custom logic. For example, it could be possible to return different icons based on something that is not part of the entity's state. + +```python +class MySwitch(SwitchEntity): + + @property + def icon(self) -> str | None: + """Icon of the entity, based on time.""" + if now().hour < 12: + return "mdi:weather-night" + return "mdi:weather-sunny" + + ... +``` + +It is not possible to provide icons for state attributes using the `icon` property. Please note that using the `icon` property is discouraged; using the above-mentioned icon translations is preferred. + ## Excluding state attributes from recorder history State attributes which are not suitable for state history recording should be excluded from state history recording by including them in either of `_entity_component_unrecorded_attributes` or `_unrecorded_attributes`.