Statistics: Add support for mean type (#24758)

* Statistics: Add support for mean type

* update

* update enum

* Update en.json
This commit is contained in:
Bram Kragten 2025-03-26 13:35:38 +01:00 committed by GitHub
parent 2717e1e6cb
commit be1e1ff9fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 113 additions and 57 deletions

View File

@ -36,13 +36,19 @@ export interface Statistic {
change: number | null; change: number | null;
} }
export enum StatisticMeanType {
NONE = 0,
ARIMETHIC = 1,
CIRCULAR = 2,
}
export interface StatisticsMetaData { export interface StatisticsMetaData {
statistics_unit_of_measurement: string | null; statistics_unit_of_measurement: string | null;
statistic_id: string; statistic_id: string;
source: string; source: string;
name?: string | null; name?: string | null;
has_sum: boolean; has_sum: boolean;
has_mean: boolean; mean_type: StatisticMeanType;
unit_class: string | null; unit_class: string | null;
} }
@ -51,6 +57,7 @@ export const STATISTIC_TYPES: StatisticsValidationResult["type"][] = [
"entity_no_longer_recorded", "entity_no_longer_recorded",
"state_class_removed", "state_class_removed",
"units_changed", "units_changed",
"mean_type_changed",
"no_state", "no_state",
]; ];
@ -59,7 +66,8 @@ export type StatisticsValidationResult =
| StatisticsValidationResultEntityNotRecorded | StatisticsValidationResultEntityNotRecorded
| StatisticsValidationResultEntityNoLongerRecorded | StatisticsValidationResultEntityNoLongerRecorded
| StatisticsValidationResultStateClassRemoved | StatisticsValidationResultStateClassRemoved
| StatisticsValidationResultUnitsChanged; | StatisticsValidationResultUnitsChanged
| StatisticsValidationResultMeanTypeChanged;
export interface StatisticsValidationResultNoState { export interface StatisticsValidationResultNoState {
type: "no_state"; type: "no_state";
@ -91,6 +99,15 @@ export interface StatisticsValidationResultUnitsChanged {
}; };
} }
export interface StatisticsValidationResultMeanTypeChanged {
type: "mean_type_changed";
data: {
statistic_id: string;
state_mean_type: StatisticMeanType;
metadata_mean_type: StatisticMeanType;
};
}
export interface StatisticsUnitConfiguration { export interface StatisticsUnitConfiguration {
energy?: "Wh" | "kWh" | "MWh" | "GJ"; energy?: "Wh" | "kWh" | "MWh" | "GJ";
power?: "W" | "kW"; power?: "W" | "kW";
@ -278,7 +295,10 @@ export const statisticsMetaHasType = (
metadata: StatisticsMetaData, metadata: StatisticsMetaData,
type: StatisticType type: StatisticType
) => { ) => {
if (mean_stat_types.includes(type) && metadata.has_mean) { if (
mean_stat_types.includes(type) &&
metadata.mean_type !== StatisticMeanType.NONE
) {
return true; return true;
} }
if (sum_stat_types.includes(type) && metadata.has_sum) { if (sum_stat_types.includes(type) && metadata.has_sum) {

View File

@ -41,6 +41,7 @@ import type {
import { import {
clearStatistics, clearStatistics,
getStatisticIds, getStatisticIds,
StatisticMeanType,
updateStatisticsIssues, updateStatisticsIssues,
validateStatistics, validateStatistics,
} from "../../../data/recorder"; } from "../../../data/recorder";
@ -57,6 +58,7 @@ const FIX_ISSUES_ORDER: Record<StatisticsValidationResult["type"], number> = {
entity_not_recorded: 1, entity_not_recorded: 1,
state_class_removed: 2, state_class_removed: 2,
units_changed: 3, units_changed: 3,
mean_type_changed: 4,
}; };
const FIXABLE_ISSUES: StatisticsValidationResult["type"][] = [ const FIXABLE_ISSUES: StatisticsValidationResult["type"][] = [
@ -64,6 +66,7 @@ const FIXABLE_ISSUES: StatisticsValidationResult["type"][] = [
"entity_no_longer_recorded", "entity_no_longer_recorded",
"state_class_removed", "state_class_removed",
"units_changed", "units_changed",
"mean_type_changed",
]; ];
type StatisticData = StatisticsMetaData & { type StatisticData = StatisticsMetaData & {
@ -641,7 +644,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
source: "", source: "",
state: this.hass.states[statisticId], state: this.hass.states[statisticId],
issues: issues[statisticId], issues: issues[statisticId],
has_mean: false, mean_type: StatisticMeanType.NONE,
has_sum: false, has_sum: false,
unit_class: null, unit_class: null,
}); });

View File

@ -57,32 +57,35 @@ export class DialogStatisticsFix extends LitElement {
{ {
name: getStatisticLabel( name: getStatisticLabel(
this.hass, this.hass,
this._params.issue.data.statistic_id, issue.data.statistic_id,
undefined undefined
), ),
statistic_id: this._params.issue.data.statistic_id, statistic_id: issue.data.statistic_id,
...(issue.type === "mean_type_changed"
? {
metadata_mean_type: this.hass.localize(
`ui.panel.developer-tools.tabs.statistics.mean_type.${issue.data.metadata_mean_type}`
),
state_mean_type: this.hass.localize(
`ui.panel.developer-tools.tabs.statistics.mean_type.${issue.data.state_mean_type}`
),
}
: {}),
} }
)}<br /><br /> )}<br /><br />
${this.hass.localize( ${this.hass.localize(
`ui.panel.developer-tools.tabs.statistics.fix_issue.${issue.type}.info_text_2`, `ui.panel.developer-tools.tabs.statistics.fix_issue.${issue.type}.info_text_2`,
{ statistic_id: issue.data.statistic_id } { statistic_id: issue.data.statistic_id }
)} )}
${issue.type === "entity_not_recorded" ${issue.type === "mean_type_changed"
? html`<br /><br /> ? html`<br /><br />
<a ${this.hass.localize(
href=${documentationUrl( "ui.panel.developer-tools.tabs.statistics.fix_issue.mean_type_changed.info_text_3",
this.hass, { statistic_id: issue.data.statistic_id }
"/integrations/recorder/#configure-filter" )}`
)} : issue.type === "entity_not_recorded"
target="_blank" ? html`<br /><br />
rel="noreferrer noopener" <a
>
${this.hass.localize(
"ui.panel.developer-tools.tabs.statistics.fix_issue.entity_not_recorded.info_text_3_link"
)}</a
>`
: issue.type === "entity_no_longer_recorded"
? html`<a
href=${documentationUrl( href=${documentationUrl(
this.hass, this.hass,
"/integrations/recorder/#configure-filter" "/integrations/recorder/#configure-filter"
@ -91,44 +94,57 @@ export class DialogStatisticsFix extends LitElement {
rel="noreferrer noopener" rel="noreferrer noopener"
> >
${this.hass.localize( ${this.hass.localize(
"ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_3_link" "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_not_recorded.info_text_3_link"
)}</a )}</a
><br /><br /> >`
${this.hass.localize( : issue.type === "entity_no_longer_recorded"
"ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_4" ? html`<a
)}` href=${documentationUrl(
: issue.type === "state_class_removed" this.hass,
? html`<ul> "/integrations/recorder/#configure-filter"
<li> )}
${this.hass.localize( target="_blank"
"ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_3" rel="noreferrer noopener"
)} >
</li> ${this.hass.localize(
<li> "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_3_link"
${this.hass.localize( )}</a
"ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_4" ><br /><br />
)}
<a
href="https://developers.home-assistant.io/docs/core/entity/sensor/#long-term-statistics"
target="_blank"
rel="noreferrer noopener"
>
${this.hass.localize(
"ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_4_link"
)}</a
>
</li>
<li>
${this.hass.localize(
"ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_5"
)}
</li>
</ul>
${this.hass.localize( ${this.hass.localize(
"ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_6", "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_4"
{ statistic_id: issue.data.statistic_id }
)}` )}`
: nothing} : issue.type === "state_class_removed"
? html`<ul>
<li>
${this.hass.localize(
"ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_3"
)}
</li>
<li>
${this.hass.localize(
"ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_4"
)}
<a
href="https://developers.home-assistant.io/docs/core/entity/sensor/#long-term-statistics"
target="_blank"
rel="noreferrer noopener"
>
${this.hass.localize(
"ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_4_link"
)}</a
>
</li>
<li>
${this.hass.localize(
"ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_5"
)}
</li>
</ul>
${this.hass.localize(
"ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_6",
{ statistic_id: issue.data.statistic_id }
)}`
: nothing}
</p> </p>
${issue.type !== "entity_not_recorded" ${issue.type !== "entity_not_recorded"

View File

@ -13,6 +13,7 @@ import type {
} from "../../../../data/recorder"; } from "../../../../data/recorder";
import { import {
getStatisticMetadata, getStatisticMetadata,
StatisticMeanType,
statisticsMetaHasType, statisticsMetaHasType,
} from "../../../../data/recorder"; } from "../../../../data/recorder";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
@ -220,7 +221,11 @@ export class HuiStatisticCardEditor
if (metadata && !metadata.has_sum && config.stat_type === "change") { if (metadata && !metadata.has_sum && config.stat_type === "change") {
config.stat_type = "mean"; config.stat_type = "mean";
} }
if (metadata && !metadata.has_mean && config.stat_type !== "change") { if (
metadata &&
metadata.mean_type === StatisticMeanType.NONE &&
config.stat_type !== "change"
) {
config.stat_type = "change"; config.stat_type = "change";
} }
} }

View File

@ -8073,6 +8073,7 @@
"no_issue": "No issue", "no_issue": "No issue",
"issues": { "issues": {
"units_changed": "The unit of this entity changed from ''{metadata_unit}'' to ''{state_unit}''.", "units_changed": "The unit of this entity changed from ''{metadata_unit}'' to ''{state_unit}''.",
"mean_type_changed": "The mean type of this entity changed from ''{metadata_mean_type}'' to ''{state_mean_type}''.",
"state_class_removed": "This entity no longer has a state class", "state_class_removed": "This entity no longer has a state class",
"entity_not_recorded": "This entity is excluded from being recorded.", "entity_not_recorded": "This entity is excluded from being recorded.",
"entity_no_longer_recorded": "This entity is no longer being recorded.", "entity_no_longer_recorded": "This entity is no longer being recorded.",
@ -8083,6 +8084,11 @@
"title": "Delete selected statistics", "title": "Delete selected statistics",
"info_text": "Do you want to permanently delete the long term statistics {statistic_count, plural,\n one {of this entity}\n other {of {statistic_count} entities}\n} from your database?" "info_text": "Do you want to permanently delete the long term statistics {statistic_count, plural,\n one {of this entity}\n other {of {statistic_count} entities}\n} from your database?"
}, },
"mean_type": {
"0": "None",
"1": "Arimethic",
"2": "Circular"
},
"fix_issue": { "fix_issue": {
"fix": "Fix issue", "fix": "Fix issue",
"clearing_failed": "Clearing the statistics failed", "clearing_failed": "Clearing the statistics failed",
@ -8131,6 +8137,12 @@
"info_text_2": "If the historic statistic values have a wrong unit, you can update the units of the old values. The values will not be updated.", "info_text_2": "If the historic statistic values have a wrong unit, you can update the units of the old values. The values will not be updated.",
"info_text_3": "Otherwise you can choose to delete all historic statistic values, and start over." "info_text_3": "Otherwise you can choose to delete all historic statistic values, and start over."
}, },
"mean_type_changed": {
"title": "The mean type has changed",
"info_text_1": "The mean type of ''{name}'' ({statistic_id}) changed from ''{metadata_mean_type}'' to ''{state_mean_type}''.",
"info_text_2": "Statistics cannot be generated until the old statistics are deleted, or the mean type matches the old statistics data again.",
"info_text_3": "Do you want to permanently delete the long term statistics of {statistic_id} from your database?"
},
"adjust_sum": { "adjust_sum": {
"title": "Adjust a statistic", "title": "Adjust a statistic",
"no_statistics_found": "No statistics found for this period.", "no_statistics_found": "No statistics found for this period.",