diff --git a/homeassistant/components/smartthings/select.py b/homeassistant/components/smartthings/select.py index 2bdd562c8b9..2f1ec0c982b 100644 --- a/homeassistant/components/smartthings/select.py +++ b/homeassistant/components/smartthings/select.py @@ -98,6 +98,7 @@ class SmartThingsSelectDescription(SelectEntityDescription): default_options: list[str] | None = None extra_components: list[str] | None = None capability_ignore_list: list[Capability] | None = None + value_is_integer: bool = False CAPABILITIES_TO_SELECT: dict[Capability | str, SmartThingsSelectDescription] = { @@ -185,6 +186,15 @@ CAPABILITIES_TO_SELECT: dict[Capability | str, SmartThingsSelectDescription] = { options_map=WASHER_WATER_TEMPERATURE_TO_HA, entity_category=EntityCategory.CONFIG, ), + Capability.SAMSUNG_CE_DUST_FILTER_ALARM: SmartThingsSelectDescription( + key=Capability.SAMSUNG_CE_DUST_FILTER_ALARM, + translation_key="dust_filter_alarm", + options_attribute=Attribute.SUPPORTED_ALARM_THRESHOLDS, + status_attribute=Attribute.ALARM_THRESHOLD, + command=Command.SET_ALARM_THRESHOLD, + entity_category=EntityCategory.CONFIG, + value_is_integer=True, + ), } @@ -253,6 +263,8 @@ class SmartThingsSelectEntity(SmartThingsEntity, SelectEntity): self.entity_description.options_map.get(option, option) for option in options ] + if self.entity_description.value_is_integer: + options = [str(option) for option in options] return options @property @@ -263,6 +275,8 @@ class SmartThingsSelectEntity(SmartThingsEntity, SelectEntity): ) if self.entity_description.options_map: option = self.entity_description.options_map.get(option) + if self.entity_description.value_is_integer and option is not None: + option = str(option) return option async def async_select_option(self, option: str) -> None: @@ -277,17 +291,20 @@ class SmartThingsSelectEntity(SmartThingsEntity, SelectEntity): raise ServiceValidationError( "Can only be updated when remote control is enabled" ) + new_option: str | int = option if self.entity_description.options_map: - option = next( + new_option = next( ( key for key, value in self.entity_description.options_map.items() if value == option ), - option, + new_option, ) + if self.entity_description.value_is_integer: + new_option = int(option) await self.execute_device_command( self.entity_description.key, self.entity_description.command, - option, + new_option, ) diff --git a/homeassistant/components/smartthings/strings.json b/homeassistant/components/smartthings/strings.json index c8888ccfb42..57f240835c9 100644 --- a/homeassistant/components/smartthings/strings.json +++ b/homeassistant/components/smartthings/strings.json @@ -161,6 +161,10 @@ "standard": "Standard" } }, + "dust_filter_alarm": { + "name": "Dust filter alarm threshold", + "unit_of_measurement": "hours" + }, "flexible_detergent_amount": { "name": "Flexible compartment dispense amount", "state": { diff --git a/tests/components/smartthings/snapshots/test_select.ambr b/tests/components/smartthings/snapshots/test_select.ambr index 118f81a6843..6dd349ad6d5 100644 --- a/tests/components/smartthings/snapshots/test_select.ambr +++ b/tests/components/smartthings/snapshots/test_select.ambr @@ -1,4 +1,126 @@ # serializer version: 1 +# name: test_all_entities[da_ac_rac_000003][select.clim_salon_dust_filter_alarm_threshold-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + '180', + '300', + '500', + '700', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': , + 'entity_id': 'select.clim_salon_dust_filter_alarm_threshold', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Dust filter alarm threshold', + 'platform': 'smartthings', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'dust_filter_alarm', + 'unique_id': '1e3f7ca2-e005-e1a4-f6d7-bc231e3f7977_main_samsungce.dustFilterAlarm_alarmThreshold_alarmThreshold', + 'unit_of_measurement': None, + }) +# --- +# name: test_all_entities[da_ac_rac_000003][select.clim_salon_dust_filter_alarm_threshold-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Clim Salon Dust filter alarm threshold', + 'options': list([ + '180', + '300', + '500', + '700', + ]), + }), + 'context': , + 'entity_id': 'select.clim_salon_dust_filter_alarm_threshold', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '500', + }) +# --- +# name: test_all_entities[da_ac_rac_01001][select.aire_dormitorio_principal_dust_filter_alarm_threshold-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + '180', + '300', + '500', + '700', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': , + 'entity_id': 'select.aire_dormitorio_principal_dust_filter_alarm_threshold', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Dust filter alarm threshold', + 'platform': 'smartthings', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'dust_filter_alarm', + 'unique_id': '4ece486b-89db-f06a-d54d-748b676b4d8e_main_samsungce.dustFilterAlarm_alarmThreshold_alarmThreshold', + 'unit_of_measurement': None, + }) +# --- +# name: test_all_entities[da_ac_rac_01001][select.aire_dormitorio_principal_dust_filter_alarm_threshold-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Aire Dormitorio Principal Dust filter alarm threshold', + 'options': list([ + '180', + '300', + '500', + '700', + ]), + }), + 'context': , + 'entity_id': 'select.aire_dormitorio_principal_dust_filter_alarm_threshold', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '500', + }) +# --- # name: test_all_entities[da_ks_microwave_0101x][select.microwave_lamp-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/smartthings/test_select.py b/tests/components/smartthings/test_select.py index 3e1746331f9..0095edc786c 100644 --- a/tests/components/smartthings/test_select.py +++ b/tests/components/smartthings/test_select.py @@ -189,3 +189,34 @@ async def test_availability_at_start( """Test unavailable at boot.""" await setup_integration(hass, mock_config_entry) assert hass.states.get("select.dryer").state == STATE_UNAVAILABLE + + +@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000003"]) +async def test_select_option_as_integer( + hass: HomeAssistant, + devices: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test selecting an option represented as an integer.""" + await setup_integration(hass, mock_config_entry) + + state = hass.states.get("select.clim_salon_dust_filter_alarm_threshold") + assert state.state == "500" + assert all(isinstance(option, str) for option in state.attributes[ATTR_OPTIONS]) + + await hass.services.async_call( + SELECT_DOMAIN, + SERVICE_SELECT_OPTION, + { + ATTR_ENTITY_ID: "select.clim_salon_dust_filter_alarm_threshold", + ATTR_OPTION: "300", + }, + blocking=True, + ) + devices.execute_device_command.assert_called_once_with( + "1e3f7ca2-e005-e1a4-f6d7-bc231e3f7977", + Capability.SAMSUNG_CE_DUST_FILTER_ALARM, + Command.SET_ALARM_THRESHOLD, + MAIN, + argument=300, + )