mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Fix adjusting statistics in ft³ (#69913)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
7e6605331d
commit
ba07663e7d
@ -12,7 +12,7 @@ import logging
|
||||
import os
|
||||
import re
|
||||
from statistics import mean
|
||||
from typing import TYPE_CHECKING, Any, Literal
|
||||
from typing import TYPE_CHECKING, Any, Literal, overload
|
||||
|
||||
from sqlalchemy import bindparam, func
|
||||
from sqlalchemy.exc import SQLAlchemyError, StatementError
|
||||
@ -123,9 +123,9 @@ QUERY_STATISTIC_META_ID = [
|
||||
STATISTICS_BAKERY = "recorder_statistics_bakery"
|
||||
|
||||
|
||||
# Convert pressure and temperature statistics from the native unit used for statistics
|
||||
# to the units configured by the user
|
||||
UNIT_CONVERSIONS = {
|
||||
# Convert pressure, temperature and volume statistics from the normalized unit used for
|
||||
# statistics to the unit configured by the user
|
||||
STATISTIC_UNIT_TO_DISPLAY_UNIT_CONVERSIONS = {
|
||||
PRESSURE_PA: lambda x, units: pressure_util.convert(
|
||||
x, PRESSURE_PA, units.pressure_unit
|
||||
)
|
||||
@ -143,6 +143,17 @@ UNIT_CONVERSIONS = {
|
||||
else None,
|
||||
}
|
||||
|
||||
# Convert volume statistics from the display unit configured by the user
|
||||
# to the normalized unit used for statistics
|
||||
# This is used to support adjusting statistics in the display unit
|
||||
DISPLAY_UNIT_TO_STATISTIC_UNIT_CONVERSIONS: dict[
|
||||
str, Callable[[float, UnitSystem], float]
|
||||
] = {
|
||||
VOLUME_CUBIC_FEET: lambda x, units: volume_util.convert(
|
||||
x, _configured_unit(VOLUME_CUBIC_METERS, units), VOLUME_CUBIC_METERS
|
||||
),
|
||||
}
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -717,7 +728,17 @@ def get_metadata(
|
||||
)
|
||||
|
||||
|
||||
@overload
|
||||
def _configured_unit(unit: None, units: UnitSystem) -> None:
|
||||
...
|
||||
|
||||
|
||||
@overload
|
||||
def _configured_unit(unit: str, units: UnitSystem) -> str:
|
||||
...
|
||||
|
||||
|
||||
def _configured_unit(unit: str | None, units: UnitSystem) -> str | None:
|
||||
"""Return the pressure and temperature units configured by the user."""
|
||||
if unit == PRESSURE_PA:
|
||||
return units.pressure_unit
|
||||
@ -1156,7 +1177,7 @@ def _sorted_statistics_to_dict(
|
||||
statistic_id = metadata[meta_id]["statistic_id"]
|
||||
convert: Callable[[Any, Any], float | None]
|
||||
if convert_units:
|
||||
convert = UNIT_CONVERSIONS.get(unit, lambda x, units: x) # type: ignore[arg-type,no-any-return]
|
||||
convert = STATISTIC_UNIT_TO_DISPLAY_UNIT_CONVERSIONS.get(unit, lambda x, units: x) # type: ignore[arg-type,no-any-return]
|
||||
else:
|
||||
convert = no_conversion
|
||||
ent_results = result[meta_id]
|
||||
@ -1316,6 +1337,12 @@ def adjust_statistics(
|
||||
if statistic_id not in metadata:
|
||||
return True
|
||||
|
||||
units = instance.hass.config.units
|
||||
statistic_unit = metadata[statistic_id][1]["unit_of_measurement"]
|
||||
display_unit = _configured_unit(statistic_unit, units)
|
||||
convert = DISPLAY_UNIT_TO_STATISTIC_UNIT_CONVERSIONS.get(display_unit, lambda x, units: x) # type: ignore[arg-type]
|
||||
sum_adjustment = convert(sum_adjustment, units)
|
||||
|
||||
_adjust_sum_statistics(
|
||||
session,
|
||||
StatisticsShortTerm,
|
||||
|
@ -325,20 +325,20 @@ def test_compile_hourly_statistics_unsupported(hass_recorder, caplog, attributes
|
||||
|
||||
@pytest.mark.parametrize("state_class", ["total"])
|
||||
@pytest.mark.parametrize(
|
||||
"units,device_class,unit,display_unit,factor,factor2",
|
||||
"units,device_class,unit,display_unit,factor",
|
||||
[
|
||||
(IMPERIAL_SYSTEM, "energy", "kWh", "kWh", 1, 1),
|
||||
(IMPERIAL_SYSTEM, "energy", "Wh", "kWh", 1 / 1000, 1),
|
||||
(IMPERIAL_SYSTEM, "monetary", "EUR", "EUR", 1, 1),
|
||||
(IMPERIAL_SYSTEM, "monetary", "SEK", "SEK", 1, 1),
|
||||
(IMPERIAL_SYSTEM, "gas", "m³", "ft³", 35.314666711, 35.314666711),
|
||||
(IMPERIAL_SYSTEM, "gas", "ft³", "ft³", 1, 35.314666711),
|
||||
(METRIC_SYSTEM, "energy", "kWh", "kWh", 1, 1),
|
||||
(METRIC_SYSTEM, "energy", "Wh", "kWh", 1 / 1000, 1),
|
||||
(METRIC_SYSTEM, "monetary", "EUR", "EUR", 1, 1),
|
||||
(METRIC_SYSTEM, "monetary", "SEK", "SEK", 1, 1),
|
||||
(METRIC_SYSTEM, "gas", "m³", "m³", 1, 1),
|
||||
(METRIC_SYSTEM, "gas", "ft³", "m³", 0.0283168466, 1),
|
||||
(IMPERIAL_SYSTEM, "energy", "kWh", "kWh", 1),
|
||||
(IMPERIAL_SYSTEM, "energy", "Wh", "kWh", 1 / 1000),
|
||||
(IMPERIAL_SYSTEM, "monetary", "EUR", "EUR", 1),
|
||||
(IMPERIAL_SYSTEM, "monetary", "SEK", "SEK", 1),
|
||||
(IMPERIAL_SYSTEM, "gas", "m³", "ft³", 35.314666711),
|
||||
(IMPERIAL_SYSTEM, "gas", "ft³", "ft³", 1),
|
||||
(METRIC_SYSTEM, "energy", "kWh", "kWh", 1),
|
||||
(METRIC_SYSTEM, "energy", "Wh", "kWh", 1 / 1000),
|
||||
(METRIC_SYSTEM, "monetary", "EUR", "EUR", 1),
|
||||
(METRIC_SYSTEM, "monetary", "SEK", "SEK", 1),
|
||||
(METRIC_SYSTEM, "gas", "m³", "m³", 1),
|
||||
(METRIC_SYSTEM, "gas", "ft³", "m³", 0.0283168466),
|
||||
],
|
||||
)
|
||||
async def test_compile_hourly_sum_statistics_amount(
|
||||
@ -351,7 +351,6 @@ async def test_compile_hourly_sum_statistics_amount(
|
||||
unit,
|
||||
display_unit,
|
||||
factor,
|
||||
factor2,
|
||||
):
|
||||
"""Test compiling hourly statistics."""
|
||||
period0 = dt_util.utcnow()
|
||||
@ -480,8 +479,8 @@ async def test_compile_hourly_sum_statistics_amount(
|
||||
assert response["success"]
|
||||
await async_wait_recording_done_without_instance(hass)
|
||||
|
||||
expected_stats["sensor.test1"][1]["sum"] = approx(factor * 40.0 + factor2 * 100)
|
||||
expected_stats["sensor.test1"][2]["sum"] = approx(factor * 70.0 + factor2 * 100)
|
||||
expected_stats["sensor.test1"][1]["sum"] = approx(factor * 40.0 + 100)
|
||||
expected_stats["sensor.test1"][2]["sum"] = approx(factor * 70.0 + 100)
|
||||
stats = statistics_during_period(hass, period0, period="5minute")
|
||||
assert stats == expected_stats
|
||||
|
||||
@ -499,8 +498,8 @@ async def test_compile_hourly_sum_statistics_amount(
|
||||
assert response["success"]
|
||||
await async_wait_recording_done_without_instance(hass)
|
||||
|
||||
expected_stats["sensor.test1"][1]["sum"] = approx(factor * 40.0 + factor2 * 100)
|
||||
expected_stats["sensor.test1"][2]["sum"] = approx(factor * 70.0 - factor2 * 300)
|
||||
expected_stats["sensor.test1"][1]["sum"] = approx(factor * 40.0 + 100)
|
||||
expected_stats["sensor.test1"][2]["sum"] = approx(factor * 70.0 - 300)
|
||||
stats = statistics_during_period(hass, period0, period="5minute")
|
||||
assert stats == expected_stats
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user