Skip to content
Snippets Groups Projects
Unverified Commit 0aa09a2d authored by Joost Lekkerkerker's avatar Joost Lekkerkerker Committed by GitHub
Browse files

Only keep valid powerConsumptionReports in SmartThings (#140049)

* power consumption report

* Only keep valid powerConsumptionReports in SmartThings
parent 62e45e39
No related branches found
No related tags found
No related merge requests found
...@@ -186,7 +186,7 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ...@@ -186,7 +186,7 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True return True
DATA_VALIDATION: dict[ KEEP_CAPABILITY_QUIRK: dict[
Capability | str, Callable[[dict[Attribute | str, Status]], bool] Capability | str, Callable[[dict[Attribute | str, Status]], bool]
] = { ] = {
Capability.WASHER_OPERATING_STATE: ( Capability.WASHER_OPERATING_STATE: (
...@@ -195,26 +195,53 @@ DATA_VALIDATION: dict[ ...@@ -195,26 +195,53 @@ DATA_VALIDATION: dict[
Capability.DEMAND_RESPONSE_LOAD_CONTROL: lambda _: True, 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( def process_status(
status: dict[str, dict[Capability | str, dict[Attribute | str, Status]]], status: dict[str, dict[Capability | str, dict[Attribute | str, Status]]],
) -> dict[str, dict[Capability | str, dict[Attribute | str, Status]]]: ) -> dict[str, dict[Capability | str, dict[Attribute | str, Status]]]:
"""Remove disabled capabilities from 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( disabled_capabilities_capability := main_component.get(
Capability.CUSTOM_DISABLED_CAPABILITIES Capability.CUSTOM_DISABLED_CAPABILITIES
) )
) is None: ) is not None:
return status disabled_capabilities = cast(
disabled_capabilities = cast( list[Capability | str],
list[Capability | str], disabled_capabilities_capability[Attribute.DISABLED_CAPABILITIES].value,
disabled_capabilities_capability[Attribute.DISABLED_CAPABILITIES].value, )
) if disabled_capabilities is not None:
if disabled_capabilities is not None: for capability in disabled_capabilities:
for capability in disabled_capabilities: if capability in main_component and (
if capability in main_component and ( capability not in KEEP_CAPABILITY_QUIRK
capability not in DATA_VALIDATION or not KEEP_CAPABILITY_QUIRK[capability](main_component[capability])
or not DATA_VALIDATION[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] del main_component[capability]
return status return status
...@@ -130,7 +130,6 @@ class SmartThingsSensorEntityDescription(SensorEntityDescription): ...@@ -130,7 +130,6 @@ class SmartThingsSensorEntityDescription(SensorEntityDescription):
unique_id_separator: str = "." unique_id_separator: str = "."
capability_ignore_list: list[set[Capability]] | None = None capability_ignore_list: list[set[Capability]] | None = None
options_attribute: Attribute | None = None options_attribute: Attribute | None = None
except_if_state_none: bool = False
CAPABILITY_TO_SENSORS: dict[ CAPABILITY_TO_SENSORS: dict[
...@@ -581,7 +580,6 @@ CAPABILITY_TO_SENSORS: dict[ ...@@ -581,7 +580,6 @@ CAPABILITY_TO_SENSORS: dict[
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_fn=lambda value: value["energy"] / 1000, value_fn=lambda value: value["energy"] / 1000,
suggested_display_precision=2, suggested_display_precision=2,
except_if_state_none=True,
), ),
SmartThingsSensorEntityDescription( SmartThingsSensorEntityDescription(
key="power_meter", key="power_meter",
...@@ -591,7 +589,6 @@ CAPABILITY_TO_SENSORS: dict[ ...@@ -591,7 +589,6 @@ CAPABILITY_TO_SENSORS: dict[
value_fn=lambda value: value["power"], value_fn=lambda value: value["power"],
extra_state_attributes_fn=power_attributes, extra_state_attributes_fn=power_attributes,
suggested_display_precision=2, suggested_display_precision=2,
except_if_state_none=True,
), ),
SmartThingsSensorEntityDescription( SmartThingsSensorEntityDescription(
key="deltaEnergy_meter", key="deltaEnergy_meter",
...@@ -601,7 +598,6 @@ CAPABILITY_TO_SENSORS: dict[ ...@@ -601,7 +598,6 @@ CAPABILITY_TO_SENSORS: dict[
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_fn=lambda value: value["deltaEnergy"] / 1000, value_fn=lambda value: value["deltaEnergy"] / 1000,
suggested_display_precision=2, suggested_display_precision=2,
except_if_state_none=True,
), ),
SmartThingsSensorEntityDescription( SmartThingsSensorEntityDescription(
key="powerEnergy_meter", key="powerEnergy_meter",
...@@ -611,7 +607,6 @@ CAPABILITY_TO_SENSORS: dict[ ...@@ -611,7 +607,6 @@ CAPABILITY_TO_SENSORS: dict[
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_fn=lambda value: value["powerEnergy"] / 1000, value_fn=lambda value: value["powerEnergy"] / 1000,
suggested_display_precision=2, suggested_display_precision=2,
except_if_state_none=True,
), ),
SmartThingsSensorEntityDescription( SmartThingsSensorEntityDescription(
key="energySaved_meter", key="energySaved_meter",
...@@ -621,7 +616,6 @@ CAPABILITY_TO_SENSORS: dict[ ...@@ -621,7 +616,6 @@ CAPABILITY_TO_SENSORS: dict[
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_fn=lambda value: value["energySaved"] / 1000, value_fn=lambda value: value["energySaved"] / 1000,
suggested_display_precision=2, suggested_display_precision=2,
except_if_state_none=True,
), ),
] ]
}, },
...@@ -983,10 +977,6 @@ async def async_setup_entry( ...@@ -983,10 +977,6 @@ async def async_setup_entry(
for capability_list in description.capability_ignore_list 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
)
) )
......
...@@ -58,6 +58,15 @@ ...@@ -58,6 +58,15 @@
"timestamp": "2025-02-08T21:56:09.761Z" "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": { "battery": {
"quantity": { "quantity": {
"value": null "value": null
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment