diff --git a/homeassistant/components/smartthings/__init__.py b/homeassistant/components/smartthings/__init__.py index cf17e6a110bd284b0ec0e7d5d1797af115061602..535a409bc8d9e3306d790067fb65cf5e59bc58bb 100644 --- a/homeassistant/components/smartthings/__init__.py +++ b/homeassistant/components/smartthings/__init__.py @@ -186,7 +186,7 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return True -DATA_VALIDATION: dict[ +KEEP_CAPABILITY_QUIRK: dict[ Capability | str, Callable[[dict[Attribute | str, Status]], bool] ] = { Capability.WASHER_OPERATING_STATE: ( @@ -195,26 +195,53 @@ DATA_VALIDATION: dict[ Capability.DEMAND_RESPONSE_LOAD_CONTROL: lambda _: True, } +POWER_CONSUMPTION_FIELDS = { + "energy", + "power", + "deltaEnergy", + "powerEnergy", + "energySaved", +} + +CAPABILITY_VALIDATION: dict[ + Capability | str, Callable[[dict[Attribute | str, Status]], bool] +] = { + Capability.POWER_CONSUMPTION_REPORT: ( + lambda status: ( + (power_consumption := status[Attribute.POWER_CONSUMPTION].value) is not None + and all( + field in cast(dict, power_consumption) + for field in POWER_CONSUMPTION_FIELDS + ) + ) + ) +} + def process_status( status: dict[str, dict[Capability | str, dict[Attribute | str, Status]]], ) -> dict[str, dict[Capability | str, dict[Attribute | str, Status]]]: """Remove disabled capabilities from status.""" - if (main_component := status.get("main")) is None or ( + if (main_component := status.get(MAIN)) is None: + return status + if ( disabled_capabilities_capability := main_component.get( Capability.CUSTOM_DISABLED_CAPABILITIES ) - ) is None: - return status - disabled_capabilities = cast( - list[Capability | str], - disabled_capabilities_capability[Attribute.DISABLED_CAPABILITIES].value, - ) - if disabled_capabilities is not None: - for capability in disabled_capabilities: - if capability in main_component and ( - capability not in DATA_VALIDATION - or not DATA_VALIDATION[capability](main_component[capability]) - ): + ) is not None: + disabled_capabilities = cast( + list[Capability | str], + disabled_capabilities_capability[Attribute.DISABLED_CAPABILITIES].value, + ) + if disabled_capabilities is not None: + for capability in disabled_capabilities: + if capability in main_component and ( + capability not in KEEP_CAPABILITY_QUIRK + or not KEEP_CAPABILITY_QUIRK[capability](main_component[capability]) + ): + del main_component[capability] + for capability in list(main_component): + if capability in CAPABILITY_VALIDATION: + if not CAPABILITY_VALIDATION[capability](main_component[capability]): del main_component[capability] return status diff --git a/homeassistant/components/smartthings/sensor.py b/homeassistant/components/smartthings/sensor.py index 22fdf3084c87267988c696cd5d1a493198028787..9ef8cb55c926c7f5cf69cfb199d194f1ddc588bd 100644 --- a/homeassistant/components/smartthings/sensor.py +++ b/homeassistant/components/smartthings/sensor.py @@ -130,7 +130,6 @@ class SmartThingsSensorEntityDescription(SensorEntityDescription): unique_id_separator: str = "." capability_ignore_list: list[set[Capability]] | None = None options_attribute: Attribute | None = None - except_if_state_none: bool = False CAPABILITY_TO_SENSORS: dict[ @@ -581,7 +580,6 @@ CAPABILITY_TO_SENSORS: dict[ native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, value_fn=lambda value: value["energy"] / 1000, suggested_display_precision=2, - except_if_state_none=True, ), SmartThingsSensorEntityDescription( key="power_meter", @@ -591,7 +589,6 @@ CAPABILITY_TO_SENSORS: dict[ value_fn=lambda value: value["power"], extra_state_attributes_fn=power_attributes, suggested_display_precision=2, - except_if_state_none=True, ), SmartThingsSensorEntityDescription( key="deltaEnergy_meter", @@ -601,7 +598,6 @@ CAPABILITY_TO_SENSORS: dict[ native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, value_fn=lambda value: value["deltaEnergy"] / 1000, suggested_display_precision=2, - except_if_state_none=True, ), SmartThingsSensorEntityDescription( key="powerEnergy_meter", @@ -611,7 +607,6 @@ CAPABILITY_TO_SENSORS: dict[ native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, value_fn=lambda value: value["powerEnergy"] / 1000, suggested_display_precision=2, - except_if_state_none=True, ), SmartThingsSensorEntityDescription( key="energySaved_meter", @@ -621,7 +616,6 @@ CAPABILITY_TO_SENSORS: dict[ native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, value_fn=lambda value: value["energySaved"] / 1000, suggested_display_precision=2, - except_if_state_none=True, ), ] }, @@ -983,10 +977,6 @@ async def async_setup_entry( for capability_list in description.capability_ignore_list ) ) - and ( - not description.except_if_state_none - or device.status[MAIN][capability][attribute].value is not None - ) ) diff --git a/tests/components/smartthings/fixtures/device_status/c2c_arlo_pro_3_switch.json b/tests/components/smartthings/fixtures/device_status/c2c_arlo_pro_3_switch.json index 371a779f83c1c1aa9a084e45d24a456941587060..a3d2cabe837ea1c1f717744533746ee902c93715 100644 --- a/tests/components/smartthings/fixtures/device_status/c2c_arlo_pro_3_switch.json +++ b/tests/components/smartthings/fixtures/device_status/c2c_arlo_pro_3_switch.json @@ -58,6 +58,15 @@ "timestamp": "2025-02-08T21:56:09.761Z" } }, + "powerConsumptionReport": { + "powerConsumption": { + "value": { + "start": "2025-02-09T15:45:29Z", + "end": "2025-02-09T16:15:33Z" + }, + "timestamp": "2025-02-09T16:15:33.639Z" + } + }, "battery": { "quantity": { "value": null