mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-22 23:59:26 +00:00
Compare commits
6 Commits
20230830.0
...
ii2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
23ba92e4ad | ||
![]() |
c636eacc51 | ||
![]() |
f75d17e10c | ||
![]() |
2c6acecb60 | ||
![]() |
225a3c3f50 | ||
![]() |
19c125f7be |
@@ -332,7 +332,10 @@ class StatisticsChart extends LitElement {
|
|||||||
prevEndTime = end;
|
prevEndTime = end;
|
||||||
};
|
};
|
||||||
|
|
||||||
const color = getGraphColorByIndex(colorIndex, this._computedStyle!);
|
const color = getGraphColorByIndex(
|
||||||
|
colorIndex,
|
||||||
|
this._computedStyle || getComputedStyle(this)
|
||||||
|
);
|
||||||
colorIndex++;
|
colorIndex++;
|
||||||
|
|
||||||
const statTypes: this["statTypes"] = [];
|
const statTypes: this["statTypes"] = [];
|
||||||
|
@@ -11,10 +11,8 @@ import {
|
|||||||
} from "date-fns/esm";
|
} from "date-fns/esm";
|
||||||
import { Collection, getCollection } from "home-assistant-js-websocket";
|
import { Collection, getCollection } from "home-assistant-js-websocket";
|
||||||
import { groupBy } from "../common/util/group-by";
|
import { groupBy } from "../common/util/group-by";
|
||||||
import { subscribeOne } from "../common/util/subscribe-one";
|
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
import { ConfigEntry, getConfigEntries } from "./config_entries";
|
import { ConfigEntry, getConfigEntries } from "./config_entries";
|
||||||
import { subscribeEntityRegistry } from "./entity_registry";
|
|
||||||
import {
|
import {
|
||||||
fetchStatistics,
|
fetchStatistics,
|
||||||
getStatisticMetadata,
|
getStatisticMetadata,
|
||||||
@@ -341,9 +339,8 @@ const getEnergyData = async (
|
|||||||
end?: Date,
|
end?: Date,
|
||||||
compare?: boolean
|
compare?: boolean
|
||||||
): Promise<EnergyData> => {
|
): Promise<EnergyData> => {
|
||||||
const [configEntries, entityRegistryEntries, info] = await Promise.all([
|
const [configEntries, info] = await Promise.all([
|
||||||
getConfigEntries(hass, { domain: "co2signal" }),
|
getConfigEntries(hass, { domain: "co2signal" }),
|
||||||
subscribeOne(hass.connection, subscribeEntityRegistry),
|
|
||||||
getEnergyInfo(hass),
|
getEnergyInfo(hass),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -352,15 +349,15 @@ const getEnergyData = async (
|
|||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
let co2SignalEntity: string | undefined;
|
let co2SignalEntity: string | undefined;
|
||||||
|
|
||||||
if (co2SignalConfigEntry) {
|
if (co2SignalConfigEntry) {
|
||||||
for (const entry of entityRegistryEntries) {
|
for (const entityId of Object.keys(hass.entities)) {
|
||||||
if (entry.config_entry_id !== co2SignalConfigEntry.entry_id) {
|
const entity = hass.entities[entityId];
|
||||||
|
if (entity.platform !== "co2signal") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The integration offers 2 entities. We want the % one.
|
// The integration offers 2 entities. We want the % one.
|
||||||
const co2State = hass.states[entry.entity_id];
|
const co2State = hass.states[entityId];
|
||||||
if (!co2State || co2State.attributes.unit_of_measurement !== "%") {
|
if (!co2State || co2State.attributes.unit_of_measurement !== "%") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -405,34 +402,35 @@ const getEnergyData = async (
|
|||||||
volume: lengthUnit === "km" ? "L" : "gal",
|
volume: lengthUnit === "km" ? "L" : "gal",
|
||||||
};
|
};
|
||||||
|
|
||||||
const stats = {
|
const _energyStats = energyStatIds.length
|
||||||
...(energyStatIds.length
|
? fetchStatistics(
|
||||||
? await fetchStatistics(
|
hass!,
|
||||||
hass!,
|
startMinHour,
|
||||||
startMinHour,
|
end,
|
||||||
end,
|
energyStatIds,
|
||||||
energyStatIds,
|
period,
|
||||||
period,
|
energyUnits,
|
||||||
energyUnits,
|
["sum"]
|
||||||
["sum"]
|
)
|
||||||
)
|
: Promise.resolve({});
|
||||||
: {}),
|
const _waterStats = waterStatIds.length
|
||||||
...(waterStatIds.length
|
? await fetchStatistics(
|
||||||
? await fetchStatistics(
|
hass!,
|
||||||
hass!,
|
startMinHour,
|
||||||
startMinHour,
|
end,
|
||||||
end,
|
waterStatIds,
|
||||||
waterStatIds,
|
period,
|
||||||
period,
|
waterUnits,
|
||||||
waterUnits,
|
["sum"]
|
||||||
["sum"]
|
)
|
||||||
)
|
: Promise.resolve({});
|
||||||
: {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
let statsCompare;
|
let statsCompare;
|
||||||
let startCompare;
|
let startCompare;
|
||||||
let endCompare;
|
let endCompare;
|
||||||
|
let _energyStatsCompare = Promise.resolve({});
|
||||||
|
let _waterStatsCompare = Promise.resolve({});
|
||||||
|
|
||||||
if (compare) {
|
if (compare) {
|
||||||
if (dayDifference > 27 && dayDifference < 32) {
|
if (dayDifference > 27 && dayDifference < 32) {
|
||||||
// When comparing a month, we want to start at the begining of the month
|
// When comparing a month, we want to start at the begining of the month
|
||||||
@@ -443,38 +441,38 @@ const getEnergyData = async (
|
|||||||
|
|
||||||
const compareStartMinHour = addHours(startCompare, -1);
|
const compareStartMinHour = addHours(startCompare, -1);
|
||||||
endCompare = addMilliseconds(start, -1);
|
endCompare = addMilliseconds(start, -1);
|
||||||
|
if (energyStatIds.length) {
|
||||||
statsCompare = {
|
_energyStatsCompare = fetchStatistics(
|
||||||
...(energyStatIds.length
|
hass!,
|
||||||
? await fetchStatistics(
|
compareStartMinHour,
|
||||||
hass!,
|
endCompare,
|
||||||
compareStartMinHour,
|
energyStatIds,
|
||||||
endCompare,
|
period,
|
||||||
energyStatIds,
|
energyUnits,
|
||||||
period,
|
["sum"]
|
||||||
energyUnits,
|
);
|
||||||
["sum"]
|
}
|
||||||
)
|
if (waterStatIds.length) {
|
||||||
: {}),
|
_waterStatsCompare = fetchStatistics(
|
||||||
...(waterStatIds.length
|
hass!,
|
||||||
? await fetchStatistics(
|
compareStartMinHour,
|
||||||
hass!,
|
endCompare,
|
||||||
compareStartMinHour,
|
waterStatIds,
|
||||||
endCompare,
|
period,
|
||||||
waterStatIds,
|
waterUnits,
|
||||||
period,
|
["sum"]
|
||||||
waterUnits,
|
);
|
||||||
["sum"]
|
}
|
||||||
)
|
|
||||||
: {}),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let fossilEnergyConsumption: FossilEnergyConsumption | undefined;
|
let _fossilEnergyConsumption:
|
||||||
let fossilEnergyConsumptionCompare: FossilEnergyConsumption | undefined;
|
| Promise<undefined>
|
||||||
|
| Promise<FossilEnergyConsumption> = Promise.resolve(undefined);
|
||||||
|
let _fossilEnergyConsumptionCompare:
|
||||||
|
| Promise<undefined>
|
||||||
|
| Promise<FossilEnergyConsumption> = Promise.resolve(undefined);
|
||||||
if (co2SignalEntity !== undefined) {
|
if (co2SignalEntity !== undefined) {
|
||||||
fossilEnergyConsumption = await getFossilEnergyConsumption(
|
_fossilEnergyConsumption = getFossilEnergyConsumption(
|
||||||
hass!,
|
hass!,
|
||||||
start,
|
start,
|
||||||
consumptionStatIDs,
|
consumptionStatIDs,
|
||||||
@@ -483,7 +481,7 @@ const getEnergyData = async (
|
|||||||
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour"
|
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour"
|
||||||
);
|
);
|
||||||
if (compare) {
|
if (compare) {
|
||||||
fossilEnergyConsumptionCompare = await getFossilEnergyConsumption(
|
_fossilEnergyConsumptionCompare = getFossilEnergyConsumption(
|
||||||
hass!,
|
hass!,
|
||||||
startCompare,
|
startCompare,
|
||||||
consumptionStatIDs,
|
consumptionStatIDs,
|
||||||
@@ -494,6 +492,37 @@ const getEnergyData = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const statsMetadata: Record<string, StatisticsMetaData> = {};
|
||||||
|
const _getStatisticMetadata: Promise<StatisticsMetaData[]> = allStatIDs.length
|
||||||
|
? getStatisticMetadata(hass, allStatIDs)
|
||||||
|
: Promise.resolve([]);
|
||||||
|
const [
|
||||||
|
energyStats,
|
||||||
|
waterStats,
|
||||||
|
energyStatsCompare,
|
||||||
|
waterStatsCompare,
|
||||||
|
statsMetadataArray,
|
||||||
|
fossilEnergyConsumption,
|
||||||
|
fossilEnergyConsumptionCompare,
|
||||||
|
] = await Promise.all([
|
||||||
|
_energyStats,
|
||||||
|
_waterStats,
|
||||||
|
_energyStatsCompare,
|
||||||
|
_waterStatsCompare,
|
||||||
|
_getStatisticMetadata,
|
||||||
|
_fossilEnergyConsumption,
|
||||||
|
_fossilEnergyConsumptionCompare,
|
||||||
|
]);
|
||||||
|
const stats = { ...energyStats, ...waterStats };
|
||||||
|
if (compare) {
|
||||||
|
statsCompare = { ...energyStatsCompare, ...waterStatsCompare };
|
||||||
|
}
|
||||||
|
if (allStatIDs.length) {
|
||||||
|
statsMetadataArray.forEach((x) => {
|
||||||
|
statsMetadata[x.statistic_id] = x;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Object.values(stats).forEach((stat) => {
|
Object.values(stats).forEach((stat) => {
|
||||||
// if the start of the first value is after the requested period, we have the first data point, and should add a zero point
|
// if the start of the first value is after the requested period, we have the first data point, and should add a zero point
|
||||||
if (stat.length && new Date(stat[0].start) > startMinHour) {
|
if (stat.length && new Date(stat[0].start) > startMinHour) {
|
||||||
@@ -507,12 +536,6 @@ const getEnergyData = async (
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const statsMetadataArray = await getStatisticMetadata(hass, allStatIDs);
|
|
||||||
const statsMetadata: Record<string, StatisticsMetaData> = {};
|
|
||||||
statsMetadataArray.forEach((x) => {
|
|
||||||
statsMetadata[x.statistic_id] = x;
|
|
||||||
});
|
|
||||||
|
|
||||||
const data: EnergyData = {
|
const data: EnergyData = {
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
|
@@ -14,6 +14,7 @@ import {
|
|||||||
getStatisticMetadata,
|
getStatisticMetadata,
|
||||||
Statistics,
|
Statistics,
|
||||||
StatisticsTypes,
|
StatisticsTypes,
|
||||||
|
StatisticsMetaData,
|
||||||
} from "../../data/recorder";
|
} from "../../data/recorder";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import "../../components/chart/statistics-chart";
|
import "../../components/chart/statistics-chart";
|
||||||
@@ -47,6 +48,8 @@ export class MoreInfoHistory extends LitElement {
|
|||||||
|
|
||||||
private _error?: string;
|
private _error?: string;
|
||||||
|
|
||||||
|
private _metadata?: Record<string, StatisticsMetaData>;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.entityId) {
|
if (!this.entityId) {
|
||||||
return html``;
|
return html``;
|
||||||
@@ -70,6 +73,7 @@ export class MoreInfoHistory extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.isLoadingData=${!this._statistics}
|
.isLoadingData=${!this._statistics}
|
||||||
.statisticsData=${this._statistics}
|
.statisticsData=${this._statistics}
|
||||||
|
.metadata=${this._metadata}
|
||||||
.statTypes=${statTypes}
|
.statTypes=${statTypes}
|
||||||
.names=${this._statNames}
|
.names=${this._statNames}
|
||||||
hideLegend
|
hideLegend
|
||||||
@@ -136,15 +140,33 @@ export class MoreInfoHistory extends LitElement {
|
|||||||
this._interval = window.setInterval(() => this._redrawGraph(), 1000 * 60);
|
this._interval = window.setInterval(() => this._redrawGraph(), 1000 * 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _getStatisticsMetaData(statisticIds: string[] | undefined) {
|
||||||
|
const statsMetadataArray = await getStatisticMetadata(
|
||||||
|
this.hass,
|
||||||
|
statisticIds
|
||||||
|
);
|
||||||
|
const statisticsMetaData = {};
|
||||||
|
statsMetadataArray.forEach((x) => {
|
||||||
|
statisticsMetaData[x.statistic_id] = x;
|
||||||
|
});
|
||||||
|
return statisticsMetaData;
|
||||||
|
}
|
||||||
|
|
||||||
private async _getStateHistory(): Promise<void> {
|
private async _getStateHistory(): Promise<void> {
|
||||||
if (
|
if (
|
||||||
isComponentLoaded(this.hass, "recorder") &&
|
isComponentLoaded(this.hass, "recorder") &&
|
||||||
computeDomain(this.entityId) === "sensor"
|
computeDomain(this.entityId) === "sensor"
|
||||||
) {
|
) {
|
||||||
const metadata = await getStatisticMetadata(this.hass, [this.entityId]);
|
const stateObj = this.hass.states[this.entityId];
|
||||||
this._statNames = { [this.entityId]: "" };
|
// If there is no state class, the integration providing the entity
|
||||||
if (metadata.length) {
|
// has not opted into statistics so there is no need to check as it
|
||||||
this._statistics = await fetchStatistics(
|
// requires another round-trip to the server.
|
||||||
|
if (stateObj && stateObj.attributes.state_class) {
|
||||||
|
// Fire off the metadata and fetch at the same time
|
||||||
|
// to avoid waiting in sequence so the UI responds
|
||||||
|
// faster.
|
||||||
|
const _metadata = this._getStatisticsMetaData([this.entityId]);
|
||||||
|
const _statistics = fetchStatistics(
|
||||||
this.hass!,
|
this.hass!,
|
||||||
subHours(new Date(), 24),
|
subHours(new Date(), 24),
|
||||||
undefined,
|
undefined,
|
||||||
@@ -153,7 +175,16 @@ export class MoreInfoHistory extends LitElement {
|
|||||||
undefined,
|
undefined,
|
||||||
statTypes
|
statTypes
|
||||||
);
|
);
|
||||||
return;
|
const [metadata, statistics] = await Promise.all([
|
||||||
|
_metadata,
|
||||||
|
_statistics,
|
||||||
|
]);
|
||||||
|
if (metadata && Object.keys(metadata).length) {
|
||||||
|
this._metadata = metadata;
|
||||||
|
this._statistics = statistics;
|
||||||
|
this._statNames = { [this.entityId]: "" };
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isComponentLoaded(this.hass, "history") || this._subscribed) {
|
if (!isComponentLoaded(this.hass, "history") || this._subscribed) {
|
||||||
|
Reference in New Issue
Block a user