diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index 31626b0b761..c01eead7e99 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -504,6 +504,17 @@ class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): return self.entity_description.suggested_unit_of_measurement return None + @cached_property + def _unit_of_measurement_translation_key(self) -> str | None: + """Return translation key for unit of measurement.""" + if self.translation_key is None: + return None + platform = self.platform + return ( + f"component.{platform.platform_name}.entity.{platform.domain}" + f".{self.translation_key}.unit_of_measurement" + ) + @final @property @override @@ -531,7 +542,14 @@ class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): ): return self.hass.config.units.temperature_unit - # Fourth priority: Native unit + # Fourth priority: Unit translation + if (translation_key := self._unit_of_measurement_translation_key) and ( + unit_of_measurement + := self.platform.default_language_platform_translations.get(translation_key) + ): + return unit_of_measurement + + # Lowest priority: Native unit return native_unit_of_measurement @final diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index 62eed213b2a..0d7614c569c 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -145,6 +145,7 @@ class EntityPlatform: self.platform_translations: dict[str, str] = {} self.object_id_component_translations: dict[str, str] = {} self.object_id_platform_translations: dict[str, str] = {} + self.default_language_platform_translations: dict[str, str] = {} self._tasks: list[asyncio.Task[None]] = [] # Stop tracking tasks after setup is completed self._setup_complete = False @@ -480,6 +481,14 @@ class EntityPlatform: self.object_id_platform_translations = await self._async_get_translations( object_id_language, "entity", self.platform_name ) + if config_language == languages.DEFAULT_LANGUAGE: + self.default_language_platform_translations = self.platform_translations + else: + self.default_language_platform_translations = ( + await self._async_get_translations( + languages.DEFAULT_LANGUAGE, "entity", self.platform_name + ) + ) def _schedule_add_entities( self, new_entities: Iterable[Entity], update_before_add: bool = False diff --git a/tests/components/brother/snapshots/test_sensor.ambr b/tests/components/brother/snapshots/test_sensor.ambr index a313e013f4b..4de85859461 100644 --- a/tests/components/brother/snapshots/test_sensor.ambr +++ b/tests/components/brother/snapshots/test_sensor.ambr @@ -31,7 +31,7 @@ 'supported_features': 0, 'translation_key': 'bw_pages', 'unique_id': '0123456789_bw_counter', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_b_w_pages-state] @@ -39,6 +39,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW B/W pages', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_b_w_pages', @@ -130,7 +131,7 @@ 'supported_features': 0, 'translation_key': 'black_drum_page_counter', 'unique_id': '0123456789_black_drum_counter', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_black_drum_page_counter-state] @@ -138,6 +139,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Black drum page counter', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_black_drum_page_counter', @@ -229,7 +231,7 @@ 'supported_features': 0, 'translation_key': 'black_drum_remaining_pages', 'unique_id': '0123456789_black_drum_remaining_pages', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_black_drum_remaining_pages-state] @@ -237,6 +239,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Black drum remaining pages', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_black_drum_remaining_pages', @@ -328,7 +331,7 @@ 'supported_features': 0, 'translation_key': 'color_pages', 'unique_id': '0123456789_color_counter', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_color_pages-state] @@ -336,6 +339,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Color pages', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_color_pages', @@ -377,7 +381,7 @@ 'supported_features': 0, 'translation_key': 'cyan_drum_page_counter', 'unique_id': '0123456789_cyan_drum_counter', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_cyan_drum_page_counter-state] @@ -385,6 +389,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Cyan drum page counter', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_cyan_drum_page_counter', @@ -476,7 +481,7 @@ 'supported_features': 0, 'translation_key': 'cyan_drum_remaining_pages', 'unique_id': '0123456789_cyan_drum_remaining_pages', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_cyan_drum_remaining_pages-state] @@ -484,6 +489,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Cyan drum remaining pages', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_cyan_drum_remaining_pages', @@ -575,7 +581,7 @@ 'supported_features': 0, 'translation_key': 'drum_page_counter', 'unique_id': '0123456789_drum_counter', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_drum_page_counter-state] @@ -583,6 +589,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Drum page counter', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_drum_page_counter', @@ -674,7 +681,7 @@ 'supported_features': 0, 'translation_key': 'drum_remaining_pages', 'unique_id': '0123456789_drum_remaining_pages', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_drum_remaining_pages-state] @@ -682,6 +689,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Drum remaining pages', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_drum_remaining_pages', @@ -723,7 +731,7 @@ 'supported_features': 0, 'translation_key': 'duplex_unit_page_counter', 'unique_id': '0123456789_duplex_unit_pages_counter', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_duplex_unit_page_counter-state] @@ -731,6 +739,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Duplex unit page counter', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_duplex_unit_page_counter', @@ -869,7 +878,7 @@ 'supported_features': 0, 'translation_key': 'magenta_drum_page_counter', 'unique_id': '0123456789_magenta_drum_counter', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_magenta_drum_page_counter-state] @@ -877,6 +886,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Magenta drum page counter', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_magenta_drum_page_counter', @@ -968,7 +978,7 @@ 'supported_features': 0, 'translation_key': 'magenta_drum_remaining_pages', 'unique_id': '0123456789_magenta_drum_remaining_pages', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_magenta_drum_remaining_pages-state] @@ -976,6 +986,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Magenta drum remaining pages', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_magenta_drum_remaining_pages', @@ -1067,7 +1078,7 @@ 'supported_features': 0, 'translation_key': 'page_counter', 'unique_id': '0123456789_page_counter', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_page_counter-state] @@ -1075,6 +1086,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Page counter', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_page_counter', @@ -1212,7 +1224,7 @@ 'supported_features': 0, 'translation_key': 'yellow_drum_page_counter', 'unique_id': '0123456789_yellow_drum_counter', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_yellow_drum_page_counter-state] @@ -1220,6 +1232,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Yellow drum page counter', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_yellow_drum_page_counter', @@ -1311,7 +1324,7 @@ 'supported_features': 0, 'translation_key': 'yellow_drum_remaining_pages', 'unique_id': '0123456789_yellow_drum_remaining_pages', - 'unit_of_measurement': None, + 'unit_of_measurement': 'pages', }) # --- # name: test_sensors[sensor.hl_l2340dw_yellow_drum_remaining_pages-state] @@ -1319,6 +1332,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'HL-L2340DW Yellow drum remaining pages', 'state_class': , + 'unit_of_measurement': 'pages', }), 'context': , 'entity_id': 'sensor.hl_l2340dw_yellow_drum_remaining_pages', diff --git a/tests/components/mastodon/snapshots/test_sensor.ambr b/tests/components/mastodon/snapshots/test_sensor.ambr index 3e6e41796f6..c8df8cdab19 100644 --- a/tests/components/mastodon/snapshots/test_sensor.ambr +++ b/tests/components/mastodon/snapshots/test_sensor.ambr @@ -31,7 +31,7 @@ 'supported_features': 0, 'translation_key': 'followers', 'unique_id': 'trwnh_mastodon_social_followers', - 'unit_of_measurement': None, + 'unit_of_measurement': 'accounts', }) # --- # name: test_sensors[sensor.mastodon_trwnh_mastodon_social_followers-state] @@ -39,6 +39,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Mastodon @trwnh@mastodon.social Followers', 'state_class': , + 'unit_of_measurement': 'accounts', }), 'context': , 'entity_id': 'sensor.mastodon_trwnh_mastodon_social_followers', @@ -80,7 +81,7 @@ 'supported_features': 0, 'translation_key': 'following', 'unique_id': 'trwnh_mastodon_social_following', - 'unit_of_measurement': None, + 'unit_of_measurement': 'accounts', }) # --- # name: test_sensors[sensor.mastodon_trwnh_mastodon_social_following-state] @@ -88,6 +89,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Mastodon @trwnh@mastodon.social Following', 'state_class': , + 'unit_of_measurement': 'accounts', }), 'context': , 'entity_id': 'sensor.mastodon_trwnh_mastodon_social_following', @@ -129,7 +131,7 @@ 'supported_features': 0, 'translation_key': 'posts', 'unique_id': 'trwnh_mastodon_social_posts', - 'unit_of_measurement': None, + 'unit_of_measurement': 'posts', }) # --- # name: test_sensors[sensor.mastodon_trwnh_mastodon_social_posts-state] @@ -137,6 +139,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Mastodon @trwnh@mastodon.social Posts', 'state_class': , + 'unit_of_measurement': 'posts', }), 'context': , 'entity_id': 'sensor.mastodon_trwnh_mastodon_social_posts', diff --git a/tests/components/mealie/snapshots/test_sensor.ambr b/tests/components/mealie/snapshots/test_sensor.ambr index d52ffc9a79a..e645cf4c45f 100644 --- a/tests/components/mealie/snapshots/test_sensor.ambr +++ b/tests/components/mealie/snapshots/test_sensor.ambr @@ -31,7 +31,7 @@ 'supported_features': 0, 'translation_key': 'categories', 'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_categories', - 'unit_of_measurement': None, + 'unit_of_measurement': 'categories', }) # --- # name: test_entities[sensor.mealie_categories-state] @@ -39,6 +39,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Mealie Categories', 'state_class': , + 'unit_of_measurement': 'categories', }), 'context': , 'entity_id': 'sensor.mealie_categories', @@ -80,7 +81,7 @@ 'supported_features': 0, 'translation_key': 'recipes', 'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_recipes', - 'unit_of_measurement': None, + 'unit_of_measurement': 'recipes', }) # --- # name: test_entities[sensor.mealie_recipes-state] @@ -88,6 +89,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Mealie Recipes', 'state_class': , + 'unit_of_measurement': 'recipes', }), 'context': , 'entity_id': 'sensor.mealie_recipes', @@ -129,7 +131,7 @@ 'supported_features': 0, 'translation_key': 'tags', 'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_tags', - 'unit_of_measurement': None, + 'unit_of_measurement': 'tags', }) # --- # name: test_entities[sensor.mealie_tags-state] @@ -137,6 +139,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Mealie Tags', 'state_class': , + 'unit_of_measurement': 'tags', }), 'context': , 'entity_id': 'sensor.mealie_tags', @@ -178,7 +181,7 @@ 'supported_features': 0, 'translation_key': 'tools', 'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_tools', - 'unit_of_measurement': None, + 'unit_of_measurement': 'tools', }) # --- # name: test_entities[sensor.mealie_tools-state] @@ -186,6 +189,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Mealie Tools', 'state_class': , + 'unit_of_measurement': 'tools', }), 'context': , 'entity_id': 'sensor.mealie_tools', @@ -227,7 +231,7 @@ 'supported_features': 0, 'translation_key': 'users', 'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_users', - 'unit_of_measurement': None, + 'unit_of_measurement': 'users', }) # --- # name: test_entities[sensor.mealie_users-state] @@ -235,6 +239,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Mealie Users', 'state_class': , + 'unit_of_measurement': 'users', }), 'context': , 'entity_id': 'sensor.mealie_users', diff --git a/tests/components/nextdns/snapshots/test_sensor.ambr b/tests/components/nextdns/snapshots/test_sensor.ambr index a1ff0941e3f..14bebea53f8 100644 --- a/tests/components/nextdns/snapshots/test_sensor.ambr +++ b/tests/components/nextdns/snapshots/test_sensor.ambr @@ -31,7 +31,7 @@ 'supported_features': 0, 'translation_key': 'doh3_queries', 'unique_id': 'xyz12_doh3_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_dns_over_http_3_queries-state] @@ -39,6 +39,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile DNS-over-HTTP/3 queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_dns_over_http_3_queries', @@ -130,7 +131,7 @@ 'supported_features': 0, 'translation_key': 'doh_queries', 'unique_id': 'xyz12_doh_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_dns_over_https_queries-state] @@ -138,6 +139,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile DNS-over-HTTPS queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_dns_over_https_queries', @@ -229,7 +231,7 @@ 'supported_features': 0, 'translation_key': 'doq_queries', 'unique_id': 'xyz12_doq_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_dns_over_quic_queries-state] @@ -237,6 +239,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile DNS-over-QUIC queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_dns_over_quic_queries', @@ -328,7 +331,7 @@ 'supported_features': 0, 'translation_key': 'dot_queries', 'unique_id': 'xyz12_dot_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_dns_over_tls_queries-state] @@ -336,6 +339,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile DNS-over-TLS queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_dns_over_tls_queries', @@ -427,7 +431,7 @@ 'supported_features': 0, 'translation_key': 'all_queries', 'unique_id': 'xyz12_all_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_dns_queries-state] @@ -435,6 +439,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile DNS queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_dns_queries', @@ -476,7 +481,7 @@ 'supported_features': 0, 'translation_key': 'blocked_queries', 'unique_id': 'xyz12_blocked_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_dns_queries_blocked-state] @@ -484,6 +489,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile DNS queries blocked', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_dns_queries_blocked', @@ -575,7 +581,7 @@ 'supported_features': 0, 'translation_key': 'relayed_queries', 'unique_id': 'xyz12_relayed_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_dns_queries_relayed-state] @@ -583,6 +589,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile DNS queries relayed', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_dns_queries_relayed', @@ -624,7 +631,7 @@ 'supported_features': 0, 'translation_key': 'not_validated_queries', 'unique_id': 'xyz12_not_validated_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_dnssec_not_validated_queries-state] @@ -632,6 +639,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile DNSSEC not validated queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_dnssec_not_validated_queries', @@ -673,7 +681,7 @@ 'supported_features': 0, 'translation_key': 'validated_queries', 'unique_id': 'xyz12_validated_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_dnssec_validated_queries-state] @@ -681,6 +689,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile DNSSEC validated queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_dnssec_validated_queries', @@ -772,7 +781,7 @@ 'supported_features': 0, 'translation_key': 'encrypted_queries', 'unique_id': 'xyz12_encrypted_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_encrypted_queries-state] @@ -780,6 +789,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile Encrypted queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_encrypted_queries', @@ -871,7 +881,7 @@ 'supported_features': 0, 'translation_key': 'ipv4_queries', 'unique_id': 'xyz12_ipv4_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_ipv4_queries-state] @@ -879,6 +889,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile IPv4 queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_ipv4_queries', @@ -920,7 +931,7 @@ 'supported_features': 0, 'translation_key': 'ipv6_queries', 'unique_id': 'xyz12_ipv6_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_ipv6_queries-state] @@ -928,6 +939,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile IPv6 queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_ipv6_queries', @@ -1019,7 +1031,7 @@ 'supported_features': 0, 'translation_key': 'tcp_queries', 'unique_id': 'xyz12_tcp_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_tcp_queries-state] @@ -1027,6 +1039,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile TCP queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_tcp_queries', @@ -1118,7 +1131,7 @@ 'supported_features': 0, 'translation_key': 'udp_queries', 'unique_id': 'xyz12_udp_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_udp_queries-state] @@ -1126,6 +1139,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile UDP queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_udp_queries', @@ -1217,7 +1231,7 @@ 'supported_features': 0, 'translation_key': 'unencrypted_queries', 'unique_id': 'xyz12_unencrypted_queries', - 'unit_of_measurement': None, + 'unit_of_measurement': 'queries', }) # --- # name: test_sensor[sensor.fake_profile_unencrypted_queries-state] @@ -1225,6 +1239,7 @@ 'attributes': ReadOnlyDict({ 'friendly_name': 'Fake Profile Unencrypted queries', 'state_class': , + 'unit_of_measurement': 'queries', }), 'context': , 'entity_id': 'sensor.fake_profile_unencrypted_queries', diff --git a/tests/components/sensor/test_init.py b/tests/components/sensor/test_init.py index 3893a089b81..48c8465c7de 100644 --- a/tests/components/sensor/test_init.py +++ b/tests/components/sensor/test_init.py @@ -7,6 +7,7 @@ from datetime import UTC, date, datetime from decimal import Decimal from types import ModuleType from typing import Any +from unittest.mock import patch import pytest @@ -484,6 +485,39 @@ async def test_restore_sensor_restore_state( assert entity0.native_unit_of_measurement == uom +async def test_translated_unit( + hass: HomeAssistant, +) -> None: + """Test translated unit.""" + + with patch( + "homeassistant.helpers.service.translation.async_get_translations", + return_value={ + "component.test.entity.sensor.test_translation_key.unit_of_measurement": "Tests" + }, + ): + entity0 = MockSensor( + name="Test", + native_value="123", + unique_id="very_unique", + ) + entity0.entity_description = SensorEntityDescription( + "test", + translation_key="test_translation_key", + native_unit_of_measurement="ignored_unit", + ) + setup_test_component_platform(hass, sensor.DOMAIN, [entity0]) + + assert await async_setup_component( + hass, "sensor", {"sensor": {"platform": "test"}} + ) + await hass.async_block_till_done() + + entity_id = entity0.entity_id + state = hass.states.get(entity_id) + assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == "Tests" + + @pytest.mark.parametrize( ( "device_class",