From 583b43955709fc77e1258371c95ff407f57ae1cf Mon Sep 17 00:00:00 2001 From: David Rapan Date: Mon, 10 Nov 2025 18:15:16 +0100 Subject: [PATCH] Add Shelly number translation (#156156) Signed-off-by: David Rapan --- homeassistant/components/shelly/number.py | 34 +++++++++++++------ homeassistant/components/shelly/strings.json | 23 +++++++++++++ .../shelly/snapshots/test_devices.ambr | 4 +-- .../shelly/snapshots/test_number.ambr | 7 ++-- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/homeassistant/components/shelly/number.py b/homeassistant/components/shelly/number.py index 29bd88a7194..7d1a1a05249 100644 --- a/homeassistant/components/shelly/number.py +++ b/homeassistant/components/shelly/number.py @@ -12,6 +12,7 @@ from aioshelly.exceptions import DeviceConnectionError, InvalidAuthError from homeassistant.components.number import ( DOMAIN as NUMBER_PLATFORM, + NumberDeviceClass, NumberEntity, NumberEntityDescription, NumberExtraStoredData, @@ -107,6 +108,9 @@ class RpcNumber(ShellyRpcAttributeEntity, NumberEntity): if description.mode_fn is not None: self._attr_mode = description.mode_fn(coordinator.device.config[key]) + if hasattr(self, "_attr_name") and description.role != ROLE_GENERIC: + delattr(self, "_attr_name") + @property def native_value(self) -> float | None: """Return value of number.""" @@ -181,7 +185,6 @@ NUMBERS: dict[tuple[str, str], BlockNumberDescription] = { ("device", "valvePos"): BlockNumberDescription( key="device|valvepos", translation_key="valve_position", - name="Valve position", native_unit_of_measurement=PERCENTAGE, available=lambda block: cast(int, block.valveError) != 1, entity_category=EntityCategory.CONFIG, @@ -200,12 +203,12 @@ RPC_NUMBERS: Final = { key="blutrv", sub_key="current_C", translation_key="external_temperature", - name="External temperature", native_min_value=-50, native_max_value=50, native_step=0.1, mode=NumberMode.BOX, entity_category=EntityCategory.CONFIG, + device_class=NumberDeviceClass.TEMPERATURE, native_unit_of_measurement=UnitOfTemperature.CELSIUS, method="blu_trv_set_external_temperature", entity_class=RpcBluTrvExtTempNumber, @@ -213,7 +216,7 @@ RPC_NUMBERS: Final = { "number_generic": RpcNumberDescription( key="number", sub_key="value", - removal_condition=lambda config, _status, key: not is_view_for_platform( + removal_condition=lambda config, _, key: not is_view_for_platform( config, key, NUMBER_PLATFORM ), max_fn=lambda config: config["max"], @@ -229,9 +232,11 @@ RPC_NUMBERS: Final = { "number_current_limit": RpcNumberDescription( key="number", sub_key="value", + translation_key="current_limit", + device_class=NumberDeviceClass.CURRENT, max_fn=lambda config: config["max"], min_fn=lambda config: config["min"], - mode_fn=lambda config: NumberMode.SLIDER, + mode_fn=lambda _: NumberMode.SLIDER, step_fn=lambda config: config["meta"]["ui"].get("step"), unit=get_virtual_component_unit, method="number_set", @@ -241,10 +246,11 @@ RPC_NUMBERS: Final = { "number_position": RpcNumberDescription( key="number", sub_key="value", + translation_key="valve_position", entity_registry_enabled_default=False, max_fn=lambda config: config["max"], min_fn=lambda config: config["min"], - mode_fn=lambda config: NumberMode.SLIDER, + mode_fn=lambda _: NumberMode.SLIDER, step_fn=lambda config: config["meta"]["ui"].get("step"), unit=get_virtual_component_unit, method="number_set", @@ -254,10 +260,12 @@ RPC_NUMBERS: Final = { "number_target_humidity": RpcNumberDescription( key="number", sub_key="value", + translation_key="target_humidity", + device_class=NumberDeviceClass.HUMIDITY, entity_registry_enabled_default=False, max_fn=lambda config: config["max"], min_fn=lambda config: config["min"], - mode_fn=lambda config: NumberMode.SLIDER, + mode_fn=lambda _: NumberMode.SLIDER, step_fn=lambda config: config["meta"]["ui"].get("step"), unit=get_virtual_component_unit, method="number_set", @@ -267,10 +275,12 @@ RPC_NUMBERS: Final = { "number_target_temperature": RpcNumberDescription( key="number", sub_key="value", + translation_key="target_temperature", + device_class=NumberDeviceClass.TEMPERATURE, entity_registry_enabled_default=False, max_fn=lambda config: config["max"], min_fn=lambda config: config["min"], - mode_fn=lambda config: NumberMode.SLIDER, + mode_fn=lambda _: NumberMode.SLIDER, step_fn=lambda config: config["meta"]["ui"].get("step"), unit=get_virtual_component_unit, method="number_set", @@ -281,21 +291,20 @@ RPC_NUMBERS: Final = { key="blutrv", sub_key="pos", translation_key="valve_position", - name="Valve position", native_min_value=0, native_max_value=100, native_step=1, mode=NumberMode.SLIDER, native_unit_of_measurement=PERCENTAGE, method="blu_trv_set_valve_position", - removal_condition=lambda config, _status, key: config[key].get("enable", True) + removal_condition=lambda config, _, key: config[key].get("enable", True) is True, entity_class=RpcBluTrvNumber, ), "left_slot_intensity": RpcNumberDescription( key="cury", sub_key="slots", - name="Left slot intensity", + translation_key="left_slot_intensity", value=lambda status, _: status["left"]["intensity"], native_min_value=0, native_max_value=100, @@ -311,7 +320,7 @@ RPC_NUMBERS: Final = { "right_slot_intensity": RpcNumberDescription( key="cury", sub_key="slots", - name="Right slot intensity", + translation_key="right_slot_intensity", value=lambda status, _: status["right"]["intensity"], native_min_value=0, native_max_value=100, @@ -402,6 +411,9 @@ class BlockSleepingNumber(ShellySleepingBlockAttributeEntity, RestoreNumber): self.restored_data: NumberExtraStoredData | None = None super().__init__(coordinator, block, attribute, description, entry) + if hasattr(self, "_attr_name"): + delattr(self, "_attr_name") + async def async_added_to_hass(self) -> None: """Handle entity which will be added.""" await super().async_added_to_hass() diff --git a/homeassistant/components/shelly/strings.json b/homeassistant/components/shelly/strings.json index 265b0233136..56e389f5023 100644 --- a/homeassistant/components/shelly/strings.json +++ b/homeassistant/components/shelly/strings.json @@ -188,6 +188,29 @@ } } }, + "number": { + "current_limit": { + "name": "Current limit" + }, + "external_temperature": { + "name": "External temperature" + }, + "left_slot_intensity": { + "name": "Left slot intensity" + }, + "right_slot_intensity": { + "name": "Right slot intensity" + }, + "target_humidity": { + "name": "Target humidity" + }, + "target_temperature": { + "name": "Target temperature" + }, + "valve_position": { + "name": "Valve position" + } + }, "select": { "cury_mode": { "name": "Mode", diff --git a/tests/components/shelly/snapshots/test_devices.ambr b/tests/components/shelly/snapshots/test_devices.ambr index 1937c9eee7b..de93c1eea77 100644 --- a/tests/components/shelly/snapshots/test_devices.ambr +++ b/tests/components/shelly/snapshots/test_devices.ambr @@ -181,7 +181,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'left_slot_intensity', 'unique_id': '123456789ABC-cury:0-left_slot_intensity', 'unit_of_measurement': '%', }) @@ -239,7 +239,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'right_slot_intensity', 'unique_id': '123456789ABC-cury:0-right_slot_intensity', 'unit_of_measurement': '%', }) diff --git a/tests/components/shelly/snapshots/test_number.ambr b/tests/components/shelly/snapshots/test_number.ambr index 93d4198b759..d1f9a90a465 100644 --- a/tests/components/shelly/snapshots/test_number.ambr +++ b/tests/components/shelly/snapshots/test_number.ambr @@ -27,7 +27,7 @@ 'name': None, 'options': dict({ }), - 'original_device_class': None, + 'original_device_class': , 'original_icon': None, 'original_name': 'External temperature', 'platform': 'shelly', @@ -42,6 +42,7 @@ # name: test_blu_trv_number_entity[number.trv_name_external_temperature-state] StateSnapshot({ 'attributes': ReadOnlyDict({ + 'device_class': 'temperature', 'friendly_name': 'TRV-Name External temperature', 'max': 50, 'min': -50, @@ -150,7 +151,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'left_slot_intensity', 'unique_id': '123456789ABC-cury:0-left_slot_intensity', 'unit_of_measurement': '%', }) @@ -208,7 +209,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'right_slot_intensity', 'unique_id': '123456789ABC-cury:0-right_slot_intensity', 'unit_of_measurement': '%', })