Move recorder statistics API to data/recorder.ts (#13672)

* Move recorder statistics API to data/recorder.ts

* Fix import

* prettier
pull/13702/head
Erik Montnemery 2022-09-12 13:23:02 +02:00 committed by GitHub
parent 1086c85964
commit d5d6216cfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 239 additions and 242 deletions

View File

@ -6,7 +6,7 @@ import {
endOfDay,
} from "date-fns/esm";
import { HassEntity } from "home-assistant-js-websocket";
import { StatisticValue } from "../../../src/data/history";
import { StatisticValue } from "../../../src/data/recorder";
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
interface HistoryQueryParams {

View File

@ -26,7 +26,7 @@ import {
statisticsHaveType,
StatisticsMetaData,
StatisticType,
} from "../../data/history";
} from "../../data/recorder";
import type { HomeAssistant } from "../../types";
import "./ha-chart-base";

View File

@ -6,7 +6,7 @@ import memoizeOne from "memoize-one";
import { fireEvent } from "../../common/dom/fire_event";
import { computeStateName } from "../../common/entity/compute_state_name";
import { stringCompare } from "../../common/string/compare";
import { getStatisticIds, StatisticsMetaData } from "../../data/history";
import { getStatisticIds, StatisticsMetaData } from "../../data/recorder";
import { PolymerChangedEvent } from "../../polymer-types";
import { HomeAssistant } from "../../types";
import { documentationUrl } from "../../util/documentation-url";

View File

@ -20,7 +20,7 @@ import {
getStatisticMetadata,
Statistics,
StatisticsMetaData,
} from "./history";
} from "./recorder";
const energyCollectionKeys: (string | undefined)[] = [];

View File

@ -1,10 +1,7 @@
import { HassEntities, HassEntity } from "home-assistant-js-websocket";
import { computeDomain } from "../common/entity/compute_domain";
import { computeStateDisplayFromEntityAttributes } from "../common/entity/compute_state_display";
import {
computeStateName,
computeStateNameFromEntityAttributes,
} from "../common/entity/compute_state_name";
import { computeStateNameFromEntityAttributes } from "../common/entity/compute_state_name";
import { LocalizeFunc } from "../common/translations/localize";
import { HomeAssistant } from "../types";
import { FrontendLocaleData } from "./translation";
@ -63,87 +60,6 @@ export interface HistoryResult {
timeline: TimelineEntity[];
}
export type StatisticType = "sum" | "min" | "max" | "mean";
export interface Statistics {
[statisticId: string]: StatisticValue[];
}
export interface StatisticValue {
statistic_id: string;
start: string;
end: string;
last_reset: string | null;
max: number | null;
mean: number | null;
min: number | null;
sum: number | null;
state: number | null;
}
export interface StatisticsMetaData {
display_unit_of_measurement: string;
statistics_unit_of_measurement: string;
statistic_id: string;
source: string;
name?: string | null;
has_sum: boolean;
has_mean: boolean;
}
export type StatisticsValidationResult =
| StatisticsValidationResultNoState
| StatisticsValidationResultEntityNotRecorded
| StatisticsValidationResultEntityNoLongerRecorded
| StatisticsValidationResultUnsupportedStateClass
| StatisticsValidationResultUnitsChanged
| StatisticsValidationResultUnsupportedUnitMetadata
| StatisticsValidationResultUnsupportedUnitState;
export interface StatisticsValidationResultNoState {
type: "no_state";
data: { statistic_id: string };
}
export interface StatisticsValidationResultEntityNoLongerRecorded {
type: "entity_no_longer_recorded";
data: { statistic_id: string };
}
export interface StatisticsValidationResultEntityNotRecorded {
type: "entity_not_recorded";
data: { statistic_id: string };
}
export interface StatisticsValidationResultUnsupportedStateClass {
type: "unsupported_state_class";
data: { statistic_id: string; state_class: string };
}
export interface StatisticsValidationResultUnitsChanged {
type: "units_changed";
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 {
[statisticId: string]: StatisticsValidationResult[];
}
export interface HistoryStates {
[entityId: string]: EntityHistoryState[];
}
@ -449,132 +365,3 @@ export const computeHistory = (
return { line: unitStates, timeline: timelineDevices };
};
// Statistics
export const getStatisticIds = (
hass: HomeAssistant,
statistic_type?: "mean" | "sum"
) =>
hass.callWS<StatisticsMetaData[]>({
type: "recorder/list_statistic_ids",
statistic_type,
});
export const getStatisticMetadata = (
hass: HomeAssistant,
statistic_ids?: string[]
) =>
hass.callWS<StatisticsMetaData[]>({
type: "recorder/get_statistics_metadata",
statistic_ids,
});
export const fetchStatistics = (
hass: HomeAssistant,
startTime: Date,
endTime?: Date,
statistic_ids?: string[],
period: "5minute" | "hour" | "day" | "month" = "hour"
) =>
hass.callWS<Statistics>({
type: "recorder/statistics_during_period",
start_time: startTime.toISOString(),
end_time: endTime?.toISOString(),
statistic_ids,
period,
});
export const validateStatistics = (hass: HomeAssistant) =>
hass.callWS<StatisticsValidationResults>({
type: "recorder/validate_statistics",
});
export const updateStatisticsMetadata = (
hass: HomeAssistant,
statistic_id: string,
unit_of_measurement: string | null
) =>
hass.callWS<void>({
type: "recorder/update_statistics_metadata",
statistic_id,
unit_of_measurement,
});
export const clearStatistics = (hass: HomeAssistant, statistic_ids: string[]) =>
hass.callWS<void>({
type: "recorder/clear_statistics",
statistic_ids,
});
export const calculateStatisticSumGrowth = (
values: StatisticValue[]
): number | null => {
if (!values || values.length < 2) {
return null;
}
const endSum = values[values.length - 1].sum;
if (endSum === null) {
return null;
}
const startSum = values[0].sum;
if (startSum === null) {
return endSum;
}
return endSum - startSum;
};
export const calculateStatisticsSumGrowth = (
data: Statistics,
stats: string[]
): number | null => {
let totalGrowth: number | null = null;
for (const stat of stats) {
if (!(stat in data)) {
continue;
}
const statGrowth = calculateStatisticSumGrowth(data[stat]);
if (statGrowth === null) {
continue;
}
if (totalGrowth === null) {
totalGrowth = statGrowth;
} else {
totalGrowth += statGrowth;
}
}
return totalGrowth;
};
export const statisticsHaveType = (
stats: StatisticValue[],
type: StatisticType
) => stats.some((stat) => stat[type] !== null);
export const adjustStatisticsSum = (
hass: HomeAssistant,
statistic_id: string,
start_time: string,
adjustment: number
): Promise<void> =>
hass.callWS({
type: "recorder/adjust_sum_statistics",
statistic_id,
start_time,
adjustment,
});
export const getStatisticLabel = (
hass: HomeAssistant,
statisticsId: string,
statisticsMetaData: StatisticsMetaData | undefined
): string => {
const entity = hass.states[statisticsId];
if (entity) {
return computeStateName(entity);
}
return statisticsMetaData?.name || statisticsId;
};

210
src/data/recorder.ts Normal file
View File

@ -0,0 +1,210 @@
import { computeStateName } from "../common/entity/compute_state_name";
import { HomeAssistant } from "../types";
export type StatisticType = "sum" | "min" | "max" | "mean";
export interface Statistics {
[statisticId: string]: StatisticValue[];
}
export interface StatisticValue {
statistic_id: string;
start: string;
end: string;
last_reset: string | null;
max: number | null;
mean: number | null;
min: number | null;
sum: number | null;
state: number | null;
}
export interface StatisticsMetaData {
display_unit_of_measurement: string;
statistics_unit_of_measurement: string;
statistic_id: string;
source: string;
name?: string | null;
has_sum: boolean;
has_mean: boolean;
}
export type StatisticsValidationResult =
| StatisticsValidationResultNoState
| StatisticsValidationResultEntityNotRecorded
| StatisticsValidationResultEntityNoLongerRecorded
| StatisticsValidationResultUnsupportedStateClass
| StatisticsValidationResultUnitsChanged
| StatisticsValidationResultUnsupportedUnitMetadata
| StatisticsValidationResultUnsupportedUnitState;
export interface StatisticsValidationResultNoState {
type: "no_state";
data: { statistic_id: string };
}
export interface StatisticsValidationResultEntityNoLongerRecorded {
type: "entity_no_longer_recorded";
data: { statistic_id: string };
}
export interface StatisticsValidationResultEntityNotRecorded {
type: "entity_not_recorded";
data: { statistic_id: string };
}
export interface StatisticsValidationResultUnsupportedStateClass {
type: "unsupported_state_class";
data: { statistic_id: string; state_class: string };
}
export interface StatisticsValidationResultUnitsChanged {
type: "units_changed";
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 {
[statisticId: string]: StatisticsValidationResult[];
}
export const getStatisticIds = (
hass: HomeAssistant,
statistic_type?: "mean" | "sum"
) =>
hass.callWS<StatisticsMetaData[]>({
type: "recorder/list_statistic_ids",
statistic_type,
});
export const getStatisticMetadata = (
hass: HomeAssistant,
statistic_ids?: string[]
) =>
hass.callWS<StatisticsMetaData[]>({
type: "recorder/get_statistics_metadata",
statistic_ids,
});
export const fetchStatistics = (
hass: HomeAssistant,
startTime: Date,
endTime?: Date,
statistic_ids?: string[],
period: "5minute" | "hour" | "day" | "month" = "hour"
) =>
hass.callWS<Statistics>({
type: "recorder/statistics_during_period",
start_time: startTime.toISOString(),
end_time: endTime?.toISOString(),
statistic_ids,
period,
});
export const validateStatistics = (hass: HomeAssistant) =>
hass.callWS<StatisticsValidationResults>({
type: "recorder/validate_statistics",
});
export const updateStatisticsMetadata = (
hass: HomeAssistant,
statistic_id: string,
unit_of_measurement: string | null
) =>
hass.callWS<void>({
type: "recorder/update_statistics_metadata",
statistic_id,
unit_of_measurement,
});
export const clearStatistics = (hass: HomeAssistant, statistic_ids: string[]) =>
hass.callWS<void>({
type: "recorder/clear_statistics",
statistic_ids,
});
export const calculateStatisticSumGrowth = (
values: StatisticValue[]
): number | null => {
if (!values || values.length < 2) {
return null;
}
const endSum = values[values.length - 1].sum;
if (endSum === null) {
return null;
}
const startSum = values[0].sum;
if (startSum === null) {
return endSum;
}
return endSum - startSum;
};
export const calculateStatisticsSumGrowth = (
data: Statistics,
stats: string[]
): number | null => {
let totalGrowth: number | null = null;
for (const stat of stats) {
if (!(stat in data)) {
continue;
}
const statGrowth = calculateStatisticSumGrowth(data[stat]);
if (statGrowth === null) {
continue;
}
if (totalGrowth === null) {
totalGrowth = statGrowth;
} else {
totalGrowth += statGrowth;
}
}
return totalGrowth;
};
export const statisticsHaveType = (
stats: StatisticValue[],
type: StatisticType
) => stats.some((stat) => stat[type] !== null);
export const adjustStatisticsSum = (
hass: HomeAssistant,
statistic_id: string,
start_time: string,
adjustment: number
): Promise<void> =>
hass.callWS({
type: "recorder/adjust_sum_statistics",
statistic_id,
start_time,
adjustment,
});
export const getStatisticLabel = (
hass: HomeAssistant,
statisticsId: string,
statisticsMetaData: StatisticsMetaData | undefined
): string => {
const entity = hass.states[statisticsId];
if (entity) {
return computeStateName(entity);
}
return statisticsMetaData?.name || statisticsId;
};

View File

@ -16,7 +16,7 @@ import {
import {
StatisticsMetaData,
getStatisticLabel,
} from "../../../../data/history";
} from "../../../../data/recorder";
import {
showAlertDialog,
showConfirmationDialog,

View File

@ -15,7 +15,7 @@ import {
import {
StatisticsMetaData,
getStatisticLabel,
} from "../../../../data/history";
} from "../../../../data/recorder";
import {
showAlertDialog,
showConfirmationDialog,

View File

@ -16,7 +16,7 @@ import {
import {
StatisticsMetaData,
getStatisticLabel,
} from "../../../../data/history";
} from "../../../../data/recorder";
import {
showAlertDialog,
showConfirmationDialog,

View File

@ -30,7 +30,7 @@ import {
import {
StatisticsMetaData,
getStatisticLabel,
} from "../../../../data/history";
} from "../../../../data/recorder";
import { showConfigFlowDialog } from "../../../../dialogs/config-flow/show-dialog-config-flow";
import {
showAlertDialog,

View File

@ -16,7 +16,7 @@ import {
import {
StatisticsMetaData,
getStatisticLabel,
} from "../../../../data/history";
} from "../../../../data/recorder";
import {
showConfirmationDialog,
showAlertDialog,

View File

@ -13,7 +13,7 @@ import {
import {
getStatisticMetadata,
StatisticsMetaData,
} from "../../../data/history";
} from "../../../data/recorder";
import "../../../layouts/hass-loading-screen";
import "../../../layouts/hass-subpage";
import { haStyle } from "../../../resources/styles";

View File

@ -15,7 +15,7 @@ import {
StatisticsMetaData,
StatisticsValidationResult,
validateStatistics,
} from "../../../data/history";
} from "../../../data/recorder";
import {
showAlertDialog,
showConfirmationDialog,

View File

@ -24,7 +24,7 @@ import {
adjustStatisticsSum,
fetchStatistics,
StatisticValue,
} from "../../../data/history";
} from "../../../data/recorder";
import type { DateTimeSelector, NumberSelector } from "../../../data/selector";
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
import { haStyle, haStyleDialog } from "../../../resources/styles";

View File

@ -8,7 +8,7 @@ import { HomeAssistant } from "../../../types";
import {
clearStatistics,
updateStatisticsMetadata,
} from "../../../data/history";
} from "../../../data/recorder";
import "../../../components/ha-formfield";
import "../../../components/ha-radio";
import type { DialogStatisticsUnitsChangedParams } from "./show-dialog-statistics-fix-units-changed";

View File

@ -5,7 +5,7 @@ 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 { updateStatisticsMetadata } from "../../../data/recorder";
import "../../../components/ha-formfield";
import "../../../components/ha-radio";
import type { DialogStatisticsUnsupportedUnitMetaParams } from "./show-dialog-statistics-fix-unsupported-unit-meta";

View File

@ -1,5 +1,5 @@
import { fireEvent } from "../../../common/dom/fire_event";
import { StatisticsMetaData } from "../../../data/history";
import { StatisticsMetaData } from "../../../data/recorder";
export const loadAdjustSumDialog = () =>
import("./dialog-statistics-adjust-sum");

View File

@ -1,5 +1,5 @@
import { fireEvent } from "../../../common/dom/fire_event";
import { StatisticsValidationResultUnitsChanged } from "../../../data/history";
import { StatisticsValidationResultUnitsChanged } from "../../../data/recorder";
export const loadFixUnitsDialog = () =>
import("./dialog-statistics-fix-units-changed");

View File

@ -1,5 +1,5 @@
import { fireEvent } from "../../../common/dom/fire_event";
import { StatisticsValidationResultUnsupportedUnitMetadata } from "../../../data/history";
import { StatisticsValidationResultUnsupportedUnitMetadata } from "../../../data/recorder";
export const loadFixUnsupportedUnitMetaDialog = () =>
import("./dialog-statistics-fix-unsupported-unit-meta");

View File

@ -13,7 +13,7 @@ import {
energySourcesByType,
getEnergyDataCollection,
} from "../../../../data/energy";
import { calculateStatisticsSumGrowth } from "../../../../data/history";
import { calculateStatisticsSumGrowth } from "../../../../data/recorder";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import type { HomeAssistant } from "../../../../types";
import { createEntityNotFoundWarning } from "../../components/hui-warning";

View File

@ -27,7 +27,7 @@ import {
fetchStatistics,
getStatisticLabel,
Statistics,
} from "../../../../data/history";
} from "../../../../data/recorder";
import { FrontendLocaleData } from "../../../../data/translation";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../../../types";

View File

@ -24,7 +24,7 @@ import {
getEnergyDataCollection,
getEnergyGasUnit,
} from "../../../../data/energy";
import { calculateStatisticsSumGrowth } from "../../../../data/history";
import { calculateStatisticsSumGrowth } from "../../../../data/recorder";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../../../types";
import { LovelaceCard } from "../../types";

View File

@ -42,7 +42,7 @@ import {
Statistics,
StatisticsMetaData,
getStatisticLabel,
} from "../../../../data/history";
} from "../../../../data/recorder";
import { FrontendLocaleData } from "../../../../data/translation";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../../../types";

View File

@ -13,7 +13,7 @@ import {
getEnergyDataCollection,
GridSourceTypeEnergyPreference,
} from "../../../../data/energy";
import { calculateStatisticsSumGrowth } from "../../../../data/history";
import { calculateStatisticsSumGrowth } from "../../../../data/recorder";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import type { HomeAssistant } from "../../../../types";
import type { LovelaceCard } from "../../types";

View File

@ -12,7 +12,7 @@ import {
energySourcesByType,
getEnergyDataCollection,
} from "../../../../data/energy";
import { calculateStatisticsSumGrowth } from "../../../../data/history";
import { calculateStatisticsSumGrowth } from "../../../../data/recorder";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import type { HomeAssistant } from "../../../../types";
import type { LovelaceCard } from "../../types";

View File

@ -43,7 +43,7 @@ import {
Statistics,
StatisticsMetaData,
getStatisticLabel,
} from "../../../../data/history";
} from "../../../../data/recorder";
import { FrontendLocaleData } from "../../../../data/translation";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../../../types";

View File

@ -30,7 +30,7 @@ import {
import {
calculateStatisticSumGrowth,
getStatisticLabel,
} from "../../../../data/history";
} from "../../../../data/recorder";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../../../types";
import { LovelaceCard } from "../../types";

View File

@ -37,7 +37,7 @@ import {
Statistics,
StatisticsMetaData,
getStatisticLabel,
} from "../../../../data/history";
} from "../../../../data/recorder";
import { FrontendLocaleData } from "../../../../data/translation";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../../../types";

View File

@ -15,7 +15,7 @@ import { hasConfigOrEntitiesChanged } from "../common/has-changed";
import { processConfigEntities } from "../common/process-config-entities";
import { LovelaceCard } from "../types";
import { StatisticsGraphCardConfig } from "./types";
import { fetchStatistics, Statistics } from "../../../data/history";
import { fetchStatistics, Statistics } from "../../../data/recorder";
@customElement("hui-statistics-graph-card")
export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard {

View File

@ -1,4 +1,4 @@
import { StatisticType } from "../../../data/history";
import { StatisticType } from "../../../data/recorder";
import { ActionConfig, LovelaceCardConfig } from "../../../data/lovelace";
import { FullCalendarView, TranslationDict } from "../../../types";
import { Condition } from "../common/validate-condition";