From 3a21c3617377d5581fbf1f9e38eaa66f7f45ad13 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Wed, 26 Feb 2025 18:19:28 +0100 Subject: [PATCH] Don't create entities for disabled capabilities in SmartThings (#139343) * Don't create entities for disabled capabilities in SmartThings * Fix * fix * fix --- .../components/smartthings/__init__.py | 28 +- .../smartthings/snapshots/test_cover.ambr | 49 -- .../smartthings/snapshots/test_sensor.ambr | 456 ------------------ 3 files changed, 26 insertions(+), 507 deletions(-) diff --git a/homeassistant/components/smartthings/__init__.py b/homeassistant/components/smartthings/__init__.py index d580e36e45e..846170552e9 100644 --- a/homeassistant/components/smartthings/__init__.py +++ b/homeassistant/components/smartthings/__init__.py @@ -4,7 +4,7 @@ from __future__ import annotations from dataclasses import dataclass import logging -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, cast from aiohttp import ClientError from pysmartthings import ( @@ -93,7 +93,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: SmartThingsConfigEntry) try: devices = await client.get_devices() for device in devices: - status = await client.get_device_status(device.device_id) + status = process_status(await client.get_device_status(device.device_id)) device_status[device.device_id] = FullDevice(device=device, status=status) except SmartThingsAuthenticationFailedError as err: raise ConfigEntryAuthFailed from err @@ -143,3 +143,27 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) return True + + +def process_status( + status: dict[str, dict[Capability, dict[Attribute, Status]]], +) -> dict[str, dict[Capability, dict[Attribute, Status]]]: + """Remove disabled capabilities from status.""" + if (main_component := status.get("main")) is None or ( + disabled_capabilities_capability := main_component.get( + Capability.CUSTOM_DISABLED_CAPABILITIES + ) + ) is None: + return status + disabled_capabilities = cast( + list[Capability], + disabled_capabilities_capability[Attribute.DISABLED_CAPABILITIES].value, + ) + for capability in disabled_capabilities: + # We still need to make sure the climate entity can work without this capability + if ( + capability in main_component + and capability != Capability.DEMAND_RESPONSE_LOAD_CONTROL + ): + del main_component[capability] + return status diff --git a/tests/components/smartthings/snapshots/test_cover.ambr b/tests/components/smartthings/snapshots/test_cover.ambr index 102be416cea..aa928c09b7a 100644 --- a/tests/components/smartthings/snapshots/test_cover.ambr +++ b/tests/components/smartthings/snapshots/test_cover.ambr @@ -49,52 +49,3 @@ 'state': 'open', }) # --- -# name: test_all_entities[da_ks_microwave_0101x][cover.microwave-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': None, - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'cover', - 'entity_category': None, - 'entity_id': 'cover.microwave', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': , - 'original_icon': None, - 'original_name': None, - 'platform': 'smartthings', - 'previous_unique_id': None, - 'supported_features': , - 'translation_key': None, - 'unique_id': '2bad3237-4886-e699-1b90-4a51a3d55c8a', - 'unit_of_measurement': None, - }) -# --- -# name: test_all_entities[da_ks_microwave_0101x][cover.microwave-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'device_class': 'door', - 'friendly_name': 'Microwave', - 'supported_features': , - }), - 'context': , - 'entity_id': 'cover.microwave', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- diff --git a/tests/components/smartthings/snapshots/test_sensor.ambr b/tests/components/smartthings/snapshots/test_sensor.ambr index f487ff632a1..778b05fa183 100644 --- a/tests/components/smartthings/snapshots/test_sensor.ambr +++ b/tests/components/smartthings/snapshots/test_sensor.ambr @@ -521,57 +521,6 @@ 'state': '15.0', }) # --- -# name: test_all_entities[da_ac_rac_000001][sensor.ac_office_granit_air_quality-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - 'state_class': , - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'sensor', - 'entity_category': None, - 'entity_id': 'sensor.ac_office_granit_air_quality', - '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': 'Air quality', - 'platform': 'smartthings', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': 'air_quality', - 'unique_id': '96a5ef74-5832-a84b-f1f7-ca799957065d.airQuality', - 'unit_of_measurement': 'CAQI', - }) -# --- -# name: test_all_entities[da_ac_rac_000001][sensor.ac_office_granit_air_quality-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'friendly_name': 'AC Office Granit Air quality', - 'state_class': , - 'unit_of_measurement': 'CAQI', - }), - 'context': , - 'entity_id': 'sensor.ac_office_granit_air_quality', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- # name: test_all_entities[da_ac_rac_000001][sensor.ac_office_granit_energy-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -780,110 +729,6 @@ 'state': '60', }) # --- -# name: test_all_entities[da_ac_rac_000001][sensor.ac_office_granit_pm10-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - 'state_class': , - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'sensor', - 'entity_category': None, - 'entity_id': 'sensor.ac_office_granit_pm10', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': , - 'original_icon': None, - 'original_name': 'PM10', - 'platform': 'smartthings', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': '96a5ef74-5832-a84b-f1f7-ca799957065d.dustLevel', - 'unit_of_measurement': 'μg/m^3', - }) -# --- -# name: test_all_entities[da_ac_rac_000001][sensor.ac_office_granit_pm10-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'device_class': 'pm10', - 'friendly_name': 'AC Office Granit PM10', - 'state_class': , - 'unit_of_measurement': 'μg/m^3', - }), - 'context': , - 'entity_id': 'sensor.ac_office_granit_pm10', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- -# name: test_all_entities[da_ac_rac_000001][sensor.ac_office_granit_pm2_5-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - 'state_class': , - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'sensor', - 'entity_category': None, - 'entity_id': 'sensor.ac_office_granit_pm2_5', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': , - 'original_icon': None, - 'original_name': 'PM2.5', - 'platform': 'smartthings', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': '96a5ef74-5832-a84b-f1f7-ca799957065d.fineDustLevel', - 'unit_of_measurement': 'μg/m^3', - }) -# --- -# name: test_all_entities[da_ac_rac_000001][sensor.ac_office_granit_pm2_5-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'device_class': 'pm25', - 'friendly_name': 'AC Office Granit PM2.5', - 'state_class': , - 'unit_of_measurement': 'μg/m^3', - }), - 'context': , - 'entity_id': 'sensor.ac_office_granit_pm2_5', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- # name: test_all_entities[da_ac_rac_000001][sensor.ac_office_granit_power-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -1090,57 +935,6 @@ 'state': '100', }) # --- -# name: test_all_entities[da_ac_rac_01001][sensor.aire_dormitorio_principal_air_quality-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - 'state_class': , - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'sensor', - 'entity_category': None, - 'entity_id': 'sensor.aire_dormitorio_principal_air_quality', - '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': 'Air quality', - 'platform': 'smartthings', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': 'air_quality', - 'unique_id': '4ece486b-89db-f06a-d54d-748b676b4d8e.airQuality', - 'unit_of_measurement': 'CAQI', - }) -# --- -# name: test_all_entities[da_ac_rac_01001][sensor.aire_dormitorio_principal_air_quality-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'friendly_name': 'Aire Dormitorio Principal Air quality', - 'state_class': , - 'unit_of_measurement': 'CAQI', - }), - 'context': , - 'entity_id': 'sensor.aire_dormitorio_principal_air_quality', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- # name: test_all_entities[da_ac_rac_01001][sensor.aire_dormitorio_principal_energy-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -1349,157 +1143,6 @@ 'state': '42', }) # --- -# name: test_all_entities[da_ac_rac_01001][sensor.aire_dormitorio_principal_odor_sensor-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': None, - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'sensor', - 'entity_category': None, - 'entity_id': 'sensor.aire_dormitorio_principal_odor_sensor', - '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': 'Odor sensor', - 'platform': 'smartthings', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': 'odor_sensor', - 'unique_id': '4ece486b-89db-f06a-d54d-748b676b4d8e.odorLevel', - 'unit_of_measurement': None, - }) -# --- -# name: test_all_entities[da_ac_rac_01001][sensor.aire_dormitorio_principal_odor_sensor-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'friendly_name': 'Aire Dormitorio Principal Odor sensor', - }), - 'context': , - 'entity_id': 'sensor.aire_dormitorio_principal_odor_sensor', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- -# name: test_all_entities[da_ac_rac_01001][sensor.aire_dormitorio_principal_pm10-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - 'state_class': , - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'sensor', - 'entity_category': None, - 'entity_id': 'sensor.aire_dormitorio_principal_pm10', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': , - 'original_icon': None, - 'original_name': 'PM10', - 'platform': 'smartthings', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': '4ece486b-89db-f06a-d54d-748b676b4d8e.dustLevel', - 'unit_of_measurement': 'µg/m³', - }) -# --- -# name: test_all_entities[da_ac_rac_01001][sensor.aire_dormitorio_principal_pm10-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'device_class': 'pm10', - 'friendly_name': 'Aire Dormitorio Principal PM10', - 'state_class': , - 'unit_of_measurement': 'µg/m³', - }), - 'context': , - 'entity_id': 'sensor.aire_dormitorio_principal_pm10', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- -# name: test_all_entities[da_ac_rac_01001][sensor.aire_dormitorio_principal_pm2_5-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - 'state_class': , - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'sensor', - 'entity_category': None, - 'entity_id': 'sensor.aire_dormitorio_principal_pm2_5', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': , - 'original_icon': None, - 'original_name': 'PM2.5', - 'platform': 'smartthings', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': '4ece486b-89db-f06a-d54d-748b676b4d8e.fineDustLevel', - 'unit_of_measurement': 'µg/m³', - }) -# --- -# name: test_all_entities[da_ac_rac_01001][sensor.aire_dormitorio_principal_pm2_5-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'device_class': 'pm25', - 'friendly_name': 'Aire Dormitorio Principal PM2.5', - 'state_class': , - 'unit_of_measurement': 'µg/m³', - }), - 'context': , - 'entity_id': 'sensor.aire_dormitorio_principal_pm2_5', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- # name: test_all_entities[da_ac_rac_01001][sensor.aire_dormitorio_principal_power-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -2101,54 +1744,6 @@ 'state': '-17', }) # --- -# name: test_all_entities[da_ref_normal_000001][sensor.refrigerator_cooling_set_point-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': None, - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'sensor', - 'entity_category': None, - 'entity_id': 'sensor.refrigerator_cooling_set_point', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': , - 'original_icon': None, - 'original_name': 'Cooling set point', - 'platform': 'smartthings', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': 'thermostat_cooling_setpoint', - 'unique_id': '7db87911-7dce-1cf2-7119-b953432a2f09.coolingSetpoint', - 'unit_of_measurement': None, - }) -# --- -# name: test_all_entities[da_ref_normal_000001][sensor.refrigerator_cooling_set_point-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'device_class': 'temperature', - 'friendly_name': 'Refrigerator Cooling set point', - }), - 'context': , - 'entity_id': 'sensor.refrigerator_cooling_set_point', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- # name: test_all_entities[da_ref_normal_000001][sensor.refrigerator_energy-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -2411,57 +2006,6 @@ 'state': '0.0135559777781698', }) # --- -# name: test_all_entities[da_ref_normal_000001][sensor.refrigerator_temperature-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - 'state_class': , - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'sensor', - 'entity_category': None, - 'entity_id': 'sensor.refrigerator_temperature', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': , - 'original_icon': None, - 'original_name': 'Temperature', - 'platform': 'smartthings', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': '7db87911-7dce-1cf2-7119-b953432a2f09.temperature', - 'unit_of_measurement': None, - }) -# --- -# name: test_all_entities[da_ref_normal_000001][sensor.refrigerator_temperature-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'device_class': 'temperature', - 'friendly_name': 'Refrigerator Temperature', - 'state_class': , - }), - 'context': , - 'entity_id': 'sensor.refrigerator_temperature', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- # name: test_all_entities[da_rvc_normal_000001][sensor.robot_vacuum_battery-entry] EntityRegistryEntrySnapshot({ 'aliases': set({