Only keep valid powerConsumptionReports in SmartThings (#140049)

* power consumption report

* Only keep valid powerConsumptionReports in SmartThings
This commit is contained in:
Joost Lekkerkerker 2025-03-07 15:04:46 +01:00 committed by Franck Nijhof
parent d6eb61e9ec
commit be32e3fe8f
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
3 changed files with 50 additions and 24 deletions

View File

@ -161,7 +161,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: (
@ -170,26 +170,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

View File

@ -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,
),
]
},
@ -976,10 +970,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
)
)

View File

@ -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