Add hob support to SmartThings (#144493)

* Add hob support to SmartThings

* Add hob support to SmartThings

* Add hob support to SmartThings

* Fix

* Update homeassistant/components/smartthings/icons.json
This commit is contained in:
Joost Lekkerkerker 2025-05-08 21:03:41 +02:00 committed by GitHub
parent 7ee9f0af2d
commit 34dbd1fb10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 577 additions and 53 deletions

View File

@ -493,6 +493,11 @@ def process_status(status: dict[str, ComponentStatus]) -> dict[str, ComponentSta
)
if disabled_components is not None:
for component in disabled_components:
# Burner components are named burner-06
# but disabledComponents contain burner-6
if "burner" in component:
burner_id = int(component.split("-")[-1])
component = f"burner-0{burner_id}"
if component in status:
del status[component]
for component_status in status.values():

View File

@ -57,6 +57,24 @@
"paused": "mdi:pause",
"finished": "mdi:food-turkey"
}
},
"manual_level": {
"default": "mdi:radiator",
"state": {
"0": "mdi:radiator-off"
}
},
"heating_mode": {
"state": {
"off": "mdi:power",
"manual": "mdi:cog",
"boost": "mdi:flash",
"keep_warm": "mdi:fire",
"quick_preheat": "mdi:heat-wave",
"defrost": "mdi:car-defrost-rear",
"melt": "mdi:snowflake-melt",
"simmer": "mdi:fire"
}
}
},
"switch": {

View File

@ -45,6 +45,17 @@ THERMOSTAT_CAPABILITIES = {
Capability.THERMOSTAT_MODE,
}
COOKTOP_HEATING_MODES = {
"off": "off",
"manual": "manual",
"boost": "boost",
"keepWarm": "keep_warm",
"quickPreheat": "quick_preheat",
"defrost": "defrost",
"melt": "melt",
"simmer": "simmer",
}
JOB_STATE_MAP = {
"airWash": "air_wash",
"airwash": "air_wash",
@ -133,6 +144,9 @@ class SmartThingsSensorEntityDescription(SensorEntityDescription):
extra_state_attributes_fn: Callable[[Any], dict[str, Any]] | None = None
capability_ignore_list: list[set[Capability]] | None = None
options_attribute: Attribute | None = None
options_map: dict[str, str] | None = None
translation_placeholders_fn: Callable[[str], dict[str, str]] | None = None
component_fn: Callable[[str], bool] | None = None
exists_fn: Callable[[Status], bool] | None = None
use_temperature_unit: bool = False
deprecated: Callable[[ComponentStatus], str | None] | None = None
@ -265,6 +279,31 @@ CAPABILITY_TO_SENSORS: dict[
)
]
},
Capability.SAMSUNG_CE_COOKTOP_HEATING_POWER: {
Attribute.MANUAL_LEVEL: [
SmartThingsSensorEntityDescription(
key=Attribute.MANUAL_LEVEL,
translation_key="manual_level",
translation_placeholders_fn=lambda component: {
"burner_id": component.split("-0")[-1]
},
component_fn=lambda component: component.startswith("burner-0"),
)
],
Attribute.HEATING_MODE: [
SmartThingsSensorEntityDescription(
key=Attribute.HEATING_MODE,
translation_key="heating_mode",
options_attribute=Attribute.SUPPORTED_HEATING_MODES,
options_map=COOKTOP_HEATING_MODES,
device_class=SensorDeviceClass.ENUM,
translation_placeholders_fn=lambda component: {
"burner_id": component.split("-0")[-1]
},
component_fn=lambda component: component.startswith("burner-0"),
)
],
},
Capability.CUSTOM_COOKTOP_OPERATING_STATE: {
Attribute.COOKTOP_OPERATING_STATE: [
SmartThingsSensorEntityDescription(
@ -1038,59 +1077,72 @@ async def async_setup_entry(
for device in entry_data.devices.values(): # pylint: disable=too-many-nested-blocks
for capability, attributes in CAPABILITY_TO_SENSORS.items():
if capability in device.status[MAIN]:
for attribute, descriptions in attributes.items():
for description in descriptions:
if (
not description.capability_ignore_list
or not any(
all(
capability in device.status[MAIN]
for capability in capability_list
)
for capability_list in description.capability_ignore_list
)
) and (
not description.exists_fn
or description.exists_fn(
device.status[MAIN][capability][attribute]
)
):
for component, capabilities in device.status.items():
if capability in capabilities:
for attribute, descriptions in attributes.items():
for description in descriptions:
if (
description.deprecated
and (
reason := description.deprecated(
device.status[MAIN]
(
not description.capability_ignore_list
or not any(
all(
capability in device.status[MAIN]
for capability in capability_list
)
for capability_list in description.capability_ignore_list
)
)
and (
not description.exists_fn
or description.exists_fn(
device.status[MAIN][capability][attribute]
)
)
and (
component == MAIN
or (
description.component_fn is not None
and description.component_fn(component)
)
)
is not None
):
if deprecate_entity(
hass,
entity_registry,
SENSOR_DOMAIN,
f"{device.device.device_id}_{MAIN}_{capability}_{attribute}_{description.key}",
f"deprecated_{reason}",
):
entities.append(
SmartThingsSensor(
entry_data.client,
device,
description,
capability,
attribute,
if (
description.deprecated
and (
reason := description.deprecated(
device.status[MAIN]
)
)
continue
entities.append(
SmartThingsSensor(
entry_data.client,
device,
description,
capability,
attribute,
is not None
):
if deprecate_entity(
hass,
entity_registry,
SENSOR_DOMAIN,
f"{device.device.device_id}_{MAIN}_{capability}_{attribute}_{description.key}",
f"deprecated_{reason}",
):
entities.append(
SmartThingsSensor(
entry_data.client,
device,
description,
MAIN,
capability,
attribute,
)
)
continue
entities.append(
SmartThingsSensor(
entry_data.client,
device,
description,
component,
capability,
attribute,
)
)
)
async_add_entities(entities)
@ -1105,6 +1157,7 @@ class SmartThingsSensor(SmartThingsEntity, SensorEntity):
client: SmartThings,
device: FullDevice,
entity_description: SmartThingsSensorEntityDescription,
component: str,
capability: Capability,
attribute: Attribute,
) -> None:
@ -1112,16 +1165,22 @@ class SmartThingsSensor(SmartThingsEntity, SensorEntity):
capabilities_to_subscribe = {capability}
if entity_description.use_temperature_unit:
capabilities_to_subscribe.add(Capability.TEMPERATURE_MEASUREMENT)
super().__init__(client, device, capabilities_to_subscribe)
self._attr_unique_id = f"{device.device.device_id}_{MAIN}_{capability}_{attribute}_{entity_description.key}"
super().__init__(client, device, capabilities_to_subscribe, component=component)
self._attr_unique_id = f"{device.device.device_id}_{component}_{capability}_{attribute}_{entity_description.key}"
self._attribute = attribute
self.capability = capability
self.entity_description = entity_description
if self.entity_description.translation_placeholders_fn:
self._attr_translation_placeholders = (
self.entity_description.translation_placeholders_fn(component)
)
@property
def native_value(self) -> str | float | datetime | int | None:
"""Return the state of the sensor."""
res = self.get_attribute_value(self.capability, self._attribute)
if options_map := self.entity_description.options_map:
return options_map.get(res)
return self.entity_description.value_fn(res)
@property
@ -1158,5 +1217,7 @@ class SmartThingsSensor(SmartThingsEntity, SensorEntity):
)
) is None:
return []
if options_map := self.entity_description.options_map:
return [options_map[option] for option in options]
return [option.lower() for option in options]
return super().options

View File

@ -181,6 +181,22 @@
"finished": "[%key:component::smartthings::entity::sensor::oven_job_state::state::finished%]"
}
},
"manual_level": {
"name": "Burner {burner_id} level"
},
"heating_mode": {
"name": "Burner {burner_id} heating mode",
"state": {
"off": "[%key:common::state::off%]",
"manual": "[%key:common::state::manual%]",
"boost": "Boost",
"keep_warm": "Keep warm",
"quick_preheat": "Quick preheat",
"defrost": "Defrost",
"melt": "Melt",
"simmer": "Simmer"
}
},
"dishwasher_machine_state": {
"name": "Machine state",
"state": {

View File

@ -9,11 +9,11 @@
},
"samsungce.cooktopHeatingPower": {
"manualLevel": {
"value": 0,
"value": 5,
"timestamp": "2025-03-26T05:57:23.203Z"
},
"heatingMode": {
"value": "manual",
"value": "boost",
"timestamp": "2025-03-25T18:18:28.550Z"
},
"manualLevelMin": {
@ -95,7 +95,7 @@
"main": {
"custom.disabledComponents": {
"disabledComponents": {
"value": ["burner-6"],
"value": ["burner-05", "burner-6"],
"timestamp": "2025-03-25T18:18:28.464Z"
}
},
@ -467,11 +467,11 @@
},
"samsungce.cooktopHeatingPower": {
"manualLevel": {
"value": 0,
"value": 2,
"timestamp": "2025-03-26T07:27:58.652Z"
},
"heatingMode": {
"value": "manual",
"value": "keepWarm",
"timestamp": "2025-03-25T18:18:28.550Z"
},
"manualLevelMin": {

View File

@ -2578,6 +2578,430 @@
'state': '27',
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_1_heating_mode-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'manual',
'boost',
'keep_warm',
]),
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.induction_hob_burner_1_heating_mode',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Burner 1 heating mode',
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'heating_mode',
'unique_id': '808dbd84-f357-47e2-a0cd-3b66fa22d584_burner-01_samsungce.cooktopHeatingPower_heatingMode_heatingMode',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_1_heating_mode-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Induction Hob Burner 1 heating mode',
'options': list([
'manual',
'boost',
'keep_warm',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.induction_hob_burner_1_heating_mode',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'manual',
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_1_level-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.induction_hob_burner_1_level',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Burner 1 level',
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'manual_level',
'unique_id': '808dbd84-f357-47e2-a0cd-3b66fa22d584_burner-01_samsungce.cooktopHeatingPower_manualLevel_manualLevel',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_1_level-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Induction Hob Burner 1 level',
}),
'context': <ANY>,
'entity_id': 'sensor.induction_hob_burner_1_level',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '0',
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_2_heating_mode-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'manual',
'boost',
'keep_warm',
]),
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.induction_hob_burner_2_heating_mode',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Burner 2 heating mode',
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'heating_mode',
'unique_id': '808dbd84-f357-47e2-a0cd-3b66fa22d584_burner-02_samsungce.cooktopHeatingPower_heatingMode_heatingMode',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_2_heating_mode-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Induction Hob Burner 2 heating mode',
'options': list([
'manual',
'boost',
'keep_warm',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.induction_hob_burner_2_heating_mode',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'boost',
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_2_level-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.induction_hob_burner_2_level',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Burner 2 level',
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'manual_level',
'unique_id': '808dbd84-f357-47e2-a0cd-3b66fa22d584_burner-02_samsungce.cooktopHeatingPower_manualLevel_manualLevel',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_2_level-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Induction Hob Burner 2 level',
}),
'context': <ANY>,
'entity_id': 'sensor.induction_hob_burner_2_level',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '5',
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_3_heating_mode-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'manual',
'boost',
'keep_warm',
]),
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.induction_hob_burner_3_heating_mode',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Burner 3 heating mode',
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'heating_mode',
'unique_id': '808dbd84-f357-47e2-a0cd-3b66fa22d584_burner-03_samsungce.cooktopHeatingPower_heatingMode_heatingMode',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_3_heating_mode-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Induction Hob Burner 3 heating mode',
'options': list([
'manual',
'boost',
'keep_warm',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.induction_hob_burner_3_heating_mode',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'keep_warm',
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_3_level-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.induction_hob_burner_3_level',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Burner 3 level',
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'manual_level',
'unique_id': '808dbd84-f357-47e2-a0cd-3b66fa22d584_burner-03_samsungce.cooktopHeatingPower_manualLevel_manualLevel',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_3_level-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Induction Hob Burner 3 level',
}),
'context': <ANY>,
'entity_id': 'sensor.induction_hob_burner_3_level',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2',
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_4_heating_mode-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'manual',
'boost',
'keep_warm',
]),
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.induction_hob_burner_4_heating_mode',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Burner 4 heating mode',
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'heating_mode',
'unique_id': '808dbd84-f357-47e2-a0cd-3b66fa22d584_burner-04_samsungce.cooktopHeatingPower_heatingMode_heatingMode',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_4_heating_mode-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Induction Hob Burner 4 heating mode',
'options': list([
'manual',
'boost',
'keep_warm',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.induction_hob_burner_4_heating_mode',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'manual',
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_4_level-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.induction_hob_burner_4_level',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Burner 4 level',
'platform': 'smartthings',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'manual_level',
'unique_id': '808dbd84-f357-47e2-a0cd-3b66fa22d584_burner-04_samsungce.cooktopHeatingPower_manualLevel_manualLevel',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_burner_4_level-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Induction Hob Burner 4 level',
}),
'context': <ANY>,
'entity_id': 'sensor.induction_hob_burner_4_level',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '0',
})
# ---
# name: test_all_entities[da_ks_cooktop_31001][sensor.induction_hob_operating_state-entry]
EntityRegistryEntrySnapshot({
'aliases': set({