mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
More statistics validation (#10146)
Co-authored-by: Philip Allgaier <mail@spacegaier.de>
This commit is contained in:
parent
dc3bad56f2
commit
6f4593508b
@ -77,18 +77,42 @@ export interface StatisticsMetaData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type StatisticsValidationResult =
|
export type StatisticsValidationResult =
|
||||||
| StatisticsValidationResultUnsupportedUnit
|
| StatisticsValidationResultEntityNotRecorded
|
||||||
| StatisticsValidationResultUnitsChanged;
|
| StatisticsValidationResultUnsupportedStateClass
|
||||||
|
| StatisticsValidationResultUnitsChanged
|
||||||
|
| StatisticsValidationResultUnsupportedUnitMetadata
|
||||||
|
| StatisticsValidationResultUnsupportedUnitState;
|
||||||
|
|
||||||
export interface StatisticsValidationResultUnsupportedUnit {
|
export interface StatisticsValidationResultEntityNotRecorded {
|
||||||
type: "unsupported_unit";
|
type: "entity_not_recorded";
|
||||||
data: { statistic_id: string; device_class: string; state_unit: string };
|
data: { statistic_id: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StatisticsValidationResultUnsupportedStateClass {
|
||||||
|
type: "unsupported_state_class";
|
||||||
|
data: { statistic_id: string; state_class: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StatisticsValidationResultUnitsChanged {
|
export interface StatisticsValidationResultUnitsChanged {
|
||||||
type: "units_changed";
|
type: "units_changed";
|
||||||
data: { statistic_id: string; state_unit: string; metadata_unit: string };
|
data: { statistic_id: string; state_unit: string; metadata_unit: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StatisticsValidationResultUnsupportedUnitMetadata {
|
||||||
|
type: "unsupported_unit_metadata";
|
||||||
|
data: {
|
||||||
|
statistic_id: string;
|
||||||
|
device_class: string;
|
||||||
|
metadata_unit: string;
|
||||||
|
supported_unit: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StatisticsValidationResultUnsupportedUnitState {
|
||||||
|
type: "unsupported_unit_state";
|
||||||
|
data: { statistic_id: string; device_class: string; metadata_unit: string };
|
||||||
|
}
|
||||||
|
|
||||||
export interface StatisticsValidationResults {
|
export interface StatisticsValidationResults {
|
||||||
[statisticId: string]: StatisticsValidationResult[];
|
[statisticId: string]: StatisticsValidationResult[];
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,15 @@ import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
|||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { showFixStatisticsUnitsChangedDialog } from "./show-dialog-statistics-fix-units-changed";
|
import { showFixStatisticsUnitsChangedDialog } from "./show-dialog-statistics-fix-units-changed";
|
||||||
|
import { showFixStatisticsUnsupportedUnitMetadataDialog } from "./show-dialog-statistics-fix-unsupported-unit-meta";
|
||||||
|
|
||||||
|
const FIX_ISSUES_ORDER = {
|
||||||
|
entity_not_recorded: 1,
|
||||||
|
unsupported_unit_state: 2,
|
||||||
|
unsupported_state_class: 3,
|
||||||
|
units_changed: 4,
|
||||||
|
unsupported_unit_metadata: 5,
|
||||||
|
};
|
||||||
@customElement("developer-tools-statistics")
|
@customElement("developer-tools-statistics")
|
||||||
class HaPanelDevStatistics extends LitElement {
|
class HaPanelDevStatistics extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
@ -119,49 +127,116 @@ class HaPanelDevStatistics extends LitElement {
|
|||||||
validateStatistics(this.hass),
|
validateStatistics(this.hass),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this._data = statisticIds.map((statistic) => ({
|
const statsIds = new Set();
|
||||||
|
|
||||||
|
this._data = statisticIds.map((statistic) => {
|
||||||
|
statsIds.add(statistic.statistic_id);
|
||||||
|
return {
|
||||||
...statistic,
|
...statistic,
|
||||||
state: this.hass.states[statistic.statistic_id],
|
state: this.hass.states[statistic.statistic_id],
|
||||||
issues: issues[statistic.statistic_id],
|
issues: issues[statistic.statistic_id],
|
||||||
}));
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(issues).forEach((statisticId) => {
|
||||||
|
if (!statsIds.has(statisticId)) {
|
||||||
|
this._data.push({
|
||||||
|
statistic_id: statisticId,
|
||||||
|
unit_of_measurement: "",
|
||||||
|
state: this.hass.states[statisticId],
|
||||||
|
issues: issues[statisticId],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _fixIssue(ev) {
|
private _fixIssue(ev) {
|
||||||
const issue = ev.currentTarget.data[0] as StatisticsValidationResult;
|
const issues = (ev.currentTarget.data as StatisticsValidationResult[]).sort(
|
||||||
if (issue.type === "unsupported_unit") {
|
(itemA, itemB) =>
|
||||||
|
(FIX_ISSUES_ORDER[itemA.type] ?? 99) -
|
||||||
|
(FIX_ISSUES_ORDER[itemB.type] ?? 99)
|
||||||
|
);
|
||||||
|
const issue = issues[0];
|
||||||
|
switch (issue.type) {
|
||||||
|
case "entity_not_recorded":
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: "Entity not recorded",
|
||||||
|
text: html`State changes of this entity are not recorded, therefore,
|
||||||
|
we can not track long term statistics for it. <br /><br />You
|
||||||
|
probably excluded this entity, or have just included some
|
||||||
|
entities.<br /><br />See the
|
||||||
|
<a
|
||||||
|
href="https://www.home-assistant.io/integrations/recorder/#configure-filter"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
>
|
||||||
|
recorder documentation</a
|
||||||
|
>
|
||||||
|
for more information.`,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "unsupported_state_class":
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: "Unsupported state class",
|
||||||
|
text: html`The state class of this entity, ${issue.data.state_class}
|
||||||
|
is not supported. <br />Statistics can not be generated until this
|
||||||
|
entity has a supported state class.<br /><br />If this state class
|
||||||
|
was provided by an integration, this is a bug. Please report an
|
||||||
|
issue.<br /><br />If you have set this state class yourself, please
|
||||||
|
correct it. The different state classes and when to use which can be
|
||||||
|
found in the
|
||||||
|
<a
|
||||||
|
href="https://developers.home-assistant.io/docs/core/entity/sensor/#long-term-statistics"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
>
|
||||||
|
developer documentation</a
|
||||||
|
>.`,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "unsupported_unit_metadata":
|
||||||
|
showFixStatisticsUnsupportedUnitMetadataDialog(this, {
|
||||||
|
issue,
|
||||||
|
fixedCallback: () => {
|
||||||
|
this._validateStatistics();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "unsupported_unit_state":
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Unsupported unit",
|
title: "Unsupported unit",
|
||||||
text: html`The unit of your entity is not a supported unit for the
|
text: html`The unit of your entity is not a supported unit for the
|
||||||
device class of the entity, ${issue.data.device_class}.
|
device class of the entity, ${issue.data.device_class}.
|
||||||
<br />Statistics can not be generated until this entity has a
|
<br />Statistics can not be generated until this entity has a
|
||||||
supported unit.<br /><br />If this unit was provided by an
|
supported unit.<br /><br />If this unit was provided by an
|
||||||
integration, this is a bug. Please report an issue.<br /><br />If you
|
integration, this is a bug. Please report an issue.<br /><br />If
|
||||||
have set this unit yourself, and want to have statistics generated,
|
you have set this unit yourself, and want to have statistics
|
||||||
make sure the unit matched the device class. The supported units are
|
generated, make sure the unit matches the device class. The
|
||||||
documented in the
|
supported units are documented in the
|
||||||
<a
|
<a
|
||||||
href="https://developers.home-assistant.io/docs/core/entity/sensor"
|
href="https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
rel="noreferrer noopener"
|
||||||
>
|
>
|
||||||
developer documentation</a
|
developer documentation</a
|
||||||
>.`,
|
>.`,
|
||||||
});
|
});
|
||||||
return;
|
break;
|
||||||
}
|
case "units_changed":
|
||||||
if (issue.type === "units_changed") {
|
|
||||||
showFixStatisticsUnitsChangedDialog(this, {
|
showFixStatisticsUnitsChangedDialog(this, {
|
||||||
issue,
|
issue,
|
||||||
fixedCallback: () => {
|
fixedCallback: () => {
|
||||||
this._validateStatistics();
|
this._validateStatistics();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return;
|
break;
|
||||||
}
|
default:
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Fix issue",
|
title: "Fix issue",
|
||||||
text: "Fixing this issue is not supported yet.",
|
text: "Fixing this issue is not supported yet.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
|
@ -0,0 +1,79 @@
|
|||||||
|
import "@material/mwc-button/mwc-button";
|
||||||
|
import { LitElement, TemplateResult, html, CSSResultGroup } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import "../../../components/ha-dialog";
|
||||||
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
|
import { haStyle, haStyleDialog } from "../../../resources/styles";
|
||||||
|
import { HomeAssistant } from "../../../types";
|
||||||
|
import { updateStatisticsMetadata } from "../../../data/history";
|
||||||
|
import "../../../components/ha-formfield";
|
||||||
|
import "../../../components/ha-radio";
|
||||||
|
import { DialogStatisticsUnsupportedUnitMetaParams } from "./show-dialog-statistics-fix-unsupported-unit-meta";
|
||||||
|
|
||||||
|
@customElement("dialog-statistics-fix-unsupported-unit-meta")
|
||||||
|
export class DialogStatisticsFixUnsupportedUnitMetadata extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private _params?: DialogStatisticsUnsupportedUnitMetaParams;
|
||||||
|
|
||||||
|
public showDialog(params: DialogStatisticsUnsupportedUnitMetaParams): void {
|
||||||
|
this._params = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog(): void {
|
||||||
|
this._params = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult | void {
|
||||||
|
if (!this._params) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-dialog
|
||||||
|
open
|
||||||
|
@closed=${this.closeDialog}
|
||||||
|
heading="Unsupported unit in recorded statistics"
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
The unit of the statistics in your database for this entity is not a
|
||||||
|
supported unit for the device class of the entity,
|
||||||
|
${this._params.issue.data.device_class}. It should be
|
||||||
|
${this._params.issue.data.supported_unit}.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Do you want to update the unit of the history statistics to
|
||||||
|
${this._params.issue.data.supported_unit}?
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<mwc-button slot="primaryAction" @click=${this._fixIssue}>
|
||||||
|
Fix
|
||||||
|
</mwc-button>
|
||||||
|
<mwc-button slot="secondaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>
|
||||||
|
</ha-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _fixIssue(): Promise<void> {
|
||||||
|
await updateStatisticsMetadata(
|
||||||
|
this.hass,
|
||||||
|
this._params!.issue.data.statistic_id,
|
||||||
|
this._params!.issue.data.supported_unit
|
||||||
|
);
|
||||||
|
this._params?.fixedCallback();
|
||||||
|
this.closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [haStyle, haStyleDialog];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"dialog-statistics-fix-unsupported-unit-meta": DialogStatisticsFixUnsupportedUnitMetadata;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
|
import { StatisticsValidationResultUnsupportedUnitMetadata } from "../../../data/history";
|
||||||
|
|
||||||
|
export const loadFixUnsupportedUnitMetaDialog = () =>
|
||||||
|
import("./dialog-statistics-fix-unsupported-unit-meta");
|
||||||
|
|
||||||
|
export interface DialogStatisticsUnsupportedUnitMetaParams {
|
||||||
|
issue: StatisticsValidationResultUnsupportedUnitMetadata;
|
||||||
|
fixedCallback: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const showFixStatisticsUnsupportedUnitMetadataDialog = (
|
||||||
|
element: HTMLElement,
|
||||||
|
detailParams: DialogStatisticsUnsupportedUnitMetaParams
|
||||||
|
): void => {
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "dialog-statistics-fix-unsupported-unit-meta",
|
||||||
|
dialogImport: loadFixUnsupportedUnitMetaDialog,
|
||||||
|
dialogParams: detailParams,
|
||||||
|
});
|
||||||
|
};
|
@ -3728,7 +3728,10 @@
|
|||||||
"issue": "Issue",
|
"issue": "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}''.",
|
||||||
"unsupported_unit": "The unit (''{state_unit}'') of this entity doesn't match a unit of device class ''{device_class}''."
|
"unsupported_unit_state": "The unit (''{state_unit}'') of this entity doesn't match a unit of device class ''{device_class}''.",
|
||||||
|
"unsupported_unit_metadata": "The unit (''{state_unit}'') of the recorded statistics doesn't match a unit of device class ''{device_class}''.",
|
||||||
|
"unsupported_state_class": "The state class ''{state_class}'' of this entity is not supported.",
|
||||||
|
"entity_not_recorded": "This entity is excluded from being recorded."
|
||||||
},
|
},
|
||||||
"fix_issue": {
|
"fix_issue": {
|
||||||
"units_changed": {
|
"units_changed": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user