Add WS API to adjust incorrect energy statistics (#65147)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
c5a3ba4065
commit
b5c5da96ac
5 changed files with 280 additions and 41 deletions
|
@ -19,6 +19,7 @@ from sqlalchemy.exc import SQLAlchemyError, StatementError
|
|||
from sqlalchemy.ext import baked
|
||||
from sqlalchemy.orm.scoping import scoped_session
|
||||
from sqlalchemy.sql.expression import literal_column, true
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import (
|
||||
PRESSURE_PA,
|
||||
|
@ -163,6 +164,14 @@ def valid_statistic_id(statistic_id: str) -> bool:
|
|||
return VALID_STATISTIC_ID.match(statistic_id) is not None
|
||||
|
||||
|
||||
def validate_statistic_id(value: str) -> str:
|
||||
"""Validate statistic ID."""
|
||||
if valid_statistic_id(value):
|
||||
return value
|
||||
|
||||
raise vol.Invalid(f"Statistics ID {value} is an invalid statistic ID")
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ValidationIssue:
|
||||
"""Error or warning message."""
|
||||
|
@ -567,6 +576,30 @@ def compile_statistics(instance: Recorder, start: datetime) -> bool:
|
|||
return True
|
||||
|
||||
|
||||
def _adjust_sum_statistics(
|
||||
session: scoped_session,
|
||||
table: type[Statistics | StatisticsShortTerm],
|
||||
metadata_id: int,
|
||||
start_time: datetime,
|
||||
adj: float,
|
||||
) -> None:
|
||||
"""Adjust statistics in the database."""
|
||||
try:
|
||||
session.query(table).filter_by(metadata_id=metadata_id).filter(
|
||||
table.start >= start_time
|
||||
).update(
|
||||
{
|
||||
table.sum: table.sum + adj,
|
||||
},
|
||||
synchronize_session=False,
|
||||
)
|
||||
except SQLAlchemyError:
|
||||
_LOGGER.exception(
|
||||
"Unexpected exception when updating statistics %s",
|
||||
id,
|
||||
)
|
||||
|
||||
|
||||
def _insert_statistics(
|
||||
session: scoped_session,
|
||||
table: type[Statistics | StatisticsShortTerm],
|
||||
|
@ -606,7 +639,7 @@ def _update_statistics(
|
|||
except SQLAlchemyError:
|
||||
_LOGGER.exception(
|
||||
"Unexpected exception when updating statistics %s:%s ",
|
||||
id,
|
||||
stat_id,
|
||||
statistic,
|
||||
)
|
||||
|
||||
|
@ -1249,7 +1282,7 @@ def add_external_statistics(
|
|||
metadata: StatisticMetaData,
|
||||
statistics: Iterable[StatisticData],
|
||||
) -> bool:
|
||||
"""Process an add_statistics job."""
|
||||
"""Process an add_external_statistics job."""
|
||||
|
||||
with session_scope(
|
||||
session=instance.get_session(), # type: ignore[misc]
|
||||
|
@ -1265,3 +1298,35 @@ def add_external_statistics(
|
|||
_insert_statistics(session, Statistics, metadata_id, stat)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@retryable_database_job("adjust_statistics")
|
||||
def adjust_statistics(
|
||||
instance: Recorder,
|
||||
statistic_id: str,
|
||||
start_time: datetime,
|
||||
sum_adjustment: float,
|
||||
) -> bool:
|
||||
"""Process an add_statistics job."""
|
||||
|
||||
with session_scope(session=instance.get_session()) as session: # type: ignore[misc]
|
||||
metadata = get_metadata_with_session(
|
||||
instance.hass, session, statistic_ids=(statistic_id,)
|
||||
)
|
||||
if statistic_id not in metadata:
|
||||
return True
|
||||
|
||||
tables: tuple[type[Statistics | StatisticsShortTerm], ...] = (
|
||||
Statistics,
|
||||
StatisticsShortTerm,
|
||||
)
|
||||
for table in tables:
|
||||
_adjust_sum_statistics(
|
||||
session,
|
||||
table,
|
||||
metadata[statistic_id][0],
|
||||
start_time,
|
||||
sum_adjustment,
|
||||
)
|
||||
|
||||
return True
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue