mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-30 08:17:20 +00:00
Improve handling of units in energy dashboard (#13454)
This commit is contained in:
parent
9b2dcbdb59
commit
1e19799da9
@ -243,8 +243,8 @@ class StatisticsChart extends LitElement {
|
|||||||
|
|
||||||
if (!this.unit) {
|
if (!this.unit) {
|
||||||
if (unit === undefined) {
|
if (unit === undefined) {
|
||||||
unit = meta?.unit_of_measurement;
|
unit = meta?.display_unit_of_measurement;
|
||||||
} else if (unit !== meta?.unit_of_measurement) {
|
} else if (unit !== meta?.display_unit_of_measurement) {
|
||||||
unit = null;
|
unit = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,23 @@ export class HaStatisticPicker extends LitElement {
|
|||||||
@property({ type: Boolean }) public disabled?: boolean;
|
@property({ type: Boolean }) public disabled?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show only statistics with these unit of measuments.
|
* Show only statistics natively stored with these units of measurements.
|
||||||
* @type {Array}
|
* @type {Array}
|
||||||
* @attr include-unit-of-measurement
|
* @attr include-statistics-unit-of-measurement
|
||||||
*/
|
*/
|
||||||
@property({ type: Array, attribute: "include-unit-of-measurement" })
|
@property({
|
||||||
public includeUnitOfMeasurement?: string[];
|
type: Array,
|
||||||
|
attribute: "include-statistics-unit-of-measurement",
|
||||||
|
})
|
||||||
|
public includeStatisticsUnitOfMeasurement?: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show only statistics displayed with these units of measurements.
|
||||||
|
* @type {Array}
|
||||||
|
* @attr include-display-unit-of-measurement
|
||||||
|
*/
|
||||||
|
@property({ type: Array, attribute: "include-display-unit-of-measurement" })
|
||||||
|
public includeDisplayUnitOfMeasurement?: string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show only statistics with these device classes.
|
* Show only statistics with these device classes.
|
||||||
@ -86,7 +97,8 @@ export class HaStatisticPicker extends LitElement {
|
|||||||
private _getStatistics = memoizeOne(
|
private _getStatistics = memoizeOne(
|
||||||
(
|
(
|
||||||
statisticIds: StatisticsMetaData[],
|
statisticIds: StatisticsMetaData[],
|
||||||
includeUnitOfMeasurement?: string[],
|
includeStatisticsUnitOfMeasurement?: string[],
|
||||||
|
includeDisplayUnitOfMeasurement?: string[],
|
||||||
includeDeviceClasses?: string[],
|
includeDeviceClasses?: string[],
|
||||||
entitiesOnly?: boolean
|
entitiesOnly?: boolean
|
||||||
): Array<{ id: string; name: string; state?: HassEntity }> => {
|
): Array<{ id: string; name: string; state?: HassEntity }> => {
|
||||||
@ -101,9 +113,18 @@ export class HaStatisticPicker extends LitElement {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeUnitOfMeasurement) {
|
if (includeStatisticsUnitOfMeasurement) {
|
||||||
statisticIds = statisticIds.filter((meta) =>
|
statisticIds = statisticIds.filter((meta) =>
|
||||||
includeUnitOfMeasurement.includes(meta.unit_of_measurement)
|
includeStatisticsUnitOfMeasurement.includes(
|
||||||
|
meta.statistics_unit_of_measurement
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (includeDisplayUnitOfMeasurement) {
|
||||||
|
statisticIds = statisticIds.filter((meta) =>
|
||||||
|
includeDisplayUnitOfMeasurement.includes(
|
||||||
|
meta.display_unit_of_measurement
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +205,8 @@ export class HaStatisticPicker extends LitElement {
|
|||||||
if (this.hasUpdated) {
|
if (this.hasUpdated) {
|
||||||
(this.comboBox as any).items = this._getStatistics(
|
(this.comboBox as any).items = this._getStatistics(
|
||||||
this.statisticIds!,
|
this.statisticIds!,
|
||||||
this.includeUnitOfMeasurement,
|
this.includeStatisticsUnitOfMeasurement,
|
||||||
|
this.includeDisplayUnitOfMeasurement,
|
||||||
this.includeDeviceClasses,
|
this.includeDeviceClasses,
|
||||||
this.entitiesOnly
|
this.entitiesOnly
|
||||||
);
|
);
|
||||||
@ -192,7 +214,8 @@ export class HaStatisticPicker extends LitElement {
|
|||||||
this.updateComplete.then(() => {
|
this.updateComplete.then(() => {
|
||||||
(this.comboBox as any).items = this._getStatistics(
|
(this.comboBox as any).items = this._getStatistics(
|
||||||
this.statisticIds!,
|
this.statisticIds!,
|
||||||
this.includeUnitOfMeasurement,
|
this.includeStatisticsUnitOfMeasurement,
|
||||||
|
this.includeDisplayUnitOfMeasurement,
|
||||||
this.includeDeviceClasses,
|
this.includeDeviceClasses,
|
||||||
this.entitiesOnly
|
this.entitiesOnly
|
||||||
);
|
);
|
||||||
|
@ -597,7 +597,7 @@ export const getEnergySolarForecasts = (hass: HomeAssistant) =>
|
|||||||
type: "energy/solar_forecast",
|
type: "energy/solar_forecast",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ENERGY_GAS_VOLUME_UNITS = ["m³", "ft³"];
|
export const ENERGY_GAS_VOLUME_UNITS = ["m³"];
|
||||||
export const ENERGY_GAS_ENERGY_UNITS = ["kWh"];
|
export const ENERGY_GAS_ENERGY_UNITS = ["kWh"];
|
||||||
export const ENERGY_GAS_UNITS = [
|
export const ENERGY_GAS_UNITS = [
|
||||||
...ENERGY_GAS_VOLUME_UNITS,
|
...ENERGY_GAS_VOLUME_UNITS,
|
||||||
@ -607,18 +607,21 @@ export const ENERGY_GAS_UNITS = [
|
|||||||
export type EnergyGasUnit = "volume" | "energy";
|
export type EnergyGasUnit = "volume" | "energy";
|
||||||
|
|
||||||
export const getEnergyGasUnitCategory = (
|
export const getEnergyGasUnitCategory = (
|
||||||
hass: HomeAssistant,
|
prefs: EnergyPreferences,
|
||||||
prefs: EnergyPreferences
|
statisticsMetaData: Record<string, StatisticsMetaData> = {},
|
||||||
|
excludeSource?: string
|
||||||
): EnergyGasUnit | undefined => {
|
): EnergyGasUnit | undefined => {
|
||||||
for (const source of prefs.energy_sources) {
|
for (const source of prefs.energy_sources) {
|
||||||
if (source.type !== "gas") {
|
if (source.type !== "gas") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (excludeSource && excludeSource === source.stat_energy_from) {
|
||||||
const entity = hass.states[source.stat_energy_from];
|
continue;
|
||||||
if (entity) {
|
}
|
||||||
|
const statisticIdWithMeta = statisticsMetaData[source.stat_energy_from];
|
||||||
|
if (statisticIdWithMeta) {
|
||||||
return ENERGY_GAS_VOLUME_UNITS.includes(
|
return ENERGY_GAS_VOLUME_UNITS.includes(
|
||||||
entity.attributes.unit_of_measurement!
|
statisticIdWithMeta.display_unit_of_measurement
|
||||||
)
|
)
|
||||||
? "volume"
|
? "volume"
|
||||||
: "energy";
|
: "energy";
|
||||||
@ -628,7 +631,6 @@ export const getEnergyGasUnitCategory = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getEnergyGasUnit = (
|
export const getEnergyGasUnit = (
|
||||||
hass: HomeAssistant,
|
|
||||||
prefs: EnergyPreferences,
|
prefs: EnergyPreferences,
|
||||||
statisticsMetaData: Record<string, StatisticsMetaData> = {}
|
statisticsMetaData: Record<string, StatisticsMetaData> = {}
|
||||||
): string | undefined => {
|
): string | undefined => {
|
||||||
@ -636,18 +638,9 @@ export const getEnergyGasUnit = (
|
|||||||
if (source.type !== "gas") {
|
if (source.type !== "gas") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const entity = hass.states[source.stat_energy_from];
|
|
||||||
if (entity?.attributes.unit_of_measurement) {
|
|
||||||
// Wh is normalized to kWh by stats generation
|
|
||||||
return entity.attributes.unit_of_measurement === "Wh"
|
|
||||||
? "kWh"
|
|
||||||
: entity.attributes.unit_of_measurement;
|
|
||||||
}
|
|
||||||
const statisticIdWithMeta = statisticsMetaData[source.stat_energy_from];
|
const statisticIdWithMeta = statisticsMetaData[source.stat_energy_from];
|
||||||
if (statisticIdWithMeta?.unit_of_measurement) {
|
if (statisticIdWithMeta?.display_unit_of_measurement) {
|
||||||
return statisticIdWithMeta.unit_of_measurement === "Wh"
|
return statisticIdWithMeta.display_unit_of_measurement;
|
||||||
? "kWh"
|
|
||||||
: statisticIdWithMeta.unit_of_measurement;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -82,7 +82,8 @@ export interface StatisticValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface StatisticsMetaData {
|
export interface StatisticsMetaData {
|
||||||
unit_of_measurement: string;
|
display_unit_of_measurement: string;
|
||||||
|
statistics_unit_of_measurement: string;
|
||||||
statistic_id: string;
|
statistic_id: string;
|
||||||
source: string;
|
source: string;
|
||||||
name?: string | null;
|
name?: string | null;
|
||||||
|
@ -133,7 +133,7 @@ export class EnergyGasSettings extends LitElement {
|
|||||||
|
|
||||||
private _addSource() {
|
private _addSource() {
|
||||||
showEnergySettingsGasDialog(this, {
|
showEnergySettingsGasDialog(this, {
|
||||||
unit: getEnergyGasUnitCategory(this.hass, this.preferences),
|
unit: getEnergyGasUnitCategory(this.preferences, this.statsMetadata),
|
||||||
saveCallback: async (source) => {
|
saveCallback: async (source) => {
|
||||||
delete source.unit_of_measurement;
|
delete source.unit_of_measurement;
|
||||||
await this._savePreferences({
|
await this._savePreferences({
|
||||||
@ -149,7 +149,11 @@ export class EnergyGasSettings extends LitElement {
|
|||||||
ev.currentTarget.closest(".row").source;
|
ev.currentTarget.closest(".row").source;
|
||||||
showEnergySettingsGasDialog(this, {
|
showEnergySettingsGasDialog(this, {
|
||||||
source: { ...origSource },
|
source: { ...origSource },
|
||||||
unit: getEnergyGasUnitCategory(this.hass, this.preferences),
|
unit: getEnergyGasUnitCategory(
|
||||||
|
this.preferences,
|
||||||
|
this.statsMetadata,
|
||||||
|
origSource.stat_energy_from
|
||||||
|
),
|
||||||
saveCallback: async (newSource) => {
|
saveCallback: async (newSource) => {
|
||||||
await this._savePreferences({
|
await this._savePreferences({
|
||||||
...this.preferences,
|
...this.preferences,
|
||||||
|
@ -67,7 +67,7 @@ export class DialogEnergyBatterySettings
|
|||||||
|
|
||||||
<ha-statistic-picker
|
<ha-statistic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.includeUnitOfMeasurement=${energyUnits}
|
.includeStatisticsUnitOfMeasurement=${energyUnits}
|
||||||
.includeDeviceClasses=${energyDeviceClasses}
|
.includeDeviceClasses=${energyDeviceClasses}
|
||||||
.value=${this._source.stat_energy_to}
|
.value=${this._source.stat_energy_to}
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
@ -79,7 +79,7 @@ export class DialogEnergyBatterySettings
|
|||||||
|
|
||||||
<ha-statistic-picker
|
<ha-statistic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.includeUnitOfMeasurement=${energyUnits}
|
.includeStatisticsUnitOfMeasurement=${energyUnits}
|
||||||
.includeDeviceClasses=${energyDeviceClasses}
|
.includeDeviceClasses=${energyDeviceClasses}
|
||||||
.value=${this._source.stat_energy_from}
|
.value=${this._source.stat_energy_from}
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
|
@ -69,7 +69,7 @@ export class DialogEnergyDeviceSettings
|
|||||||
|
|
||||||
<ha-statistic-picker
|
<ha-statistic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.includeUnitOfMeasurement=${energyUnits}
|
.includeStatisticsUnitOfMeasurement=${energyUnits}
|
||||||
.includeDeviceClasses=${energyDeviceClasses}
|
.includeDeviceClasses=${energyDeviceClasses}
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.energy.device_consumption.dialog.device_consumption_energy"
|
"ui.panel.config.energy.device_consumption.dialog.device_consumption_energy"
|
||||||
|
@ -90,7 +90,7 @@ export class DialogEnergyGasSettings
|
|||||||
|
|
||||||
<ha-statistic-picker
|
<ha-statistic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.includeUnitOfMeasurement=${this._params.unit === undefined
|
.includeStatisticsUnitOfMeasurement=${this._params.unit === undefined
|
||||||
? ENERGY_GAS_UNITS
|
? ENERGY_GAS_UNITS
|
||||||
: this._params.unit === "energy"
|
: this._params.unit === "energy"
|
||||||
? ENERGY_GAS_ENERGY_UNITS
|
? ENERGY_GAS_ENERGY_UNITS
|
||||||
|
@ -93,7 +93,7 @@ export class DialogEnergyGridFlowSettings
|
|||||||
|
|
||||||
<ha-statistic-picker
|
<ha-statistic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.includeUnitOfMeasurement=${energyUnits}
|
.includeStatisticsUnitOfMeasurement=${energyUnits}
|
||||||
.includeDeviceClasses=${energyDeviceClasses}
|
.includeDeviceClasses=${energyDeviceClasses}
|
||||||
.value=${this._source[
|
.value=${this._source[
|
||||||
this._params.direction === "from"
|
this._params.direction === "from"
|
||||||
|
@ -79,7 +79,7 @@ export class DialogEnergySolarSettings
|
|||||||
|
|
||||||
<ha-statistic-picker
|
<ha-statistic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.includeUnitOfMeasurement=${energyUnits}
|
.includeStatisticsUnitOfMeasurement=${energyUnits}
|
||||||
.includeDeviceClasses=${energyDeviceClasses}
|
.includeDeviceClasses=${energyDeviceClasses}
|
||||||
.value=${this._source.stat_energy_from}
|
.value=${this._source.stat_energy_from}
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
|
@ -211,7 +211,8 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
|
|||||||
) {
|
) {
|
||||||
this._data.push({
|
this._data.push({
|
||||||
statistic_id: statisticId,
|
statistic_id: statisticId,
|
||||||
unit_of_measurement: "",
|
statistics_unit_of_measurement: "",
|
||||||
|
display_unit_of_measurement: "",
|
||||||
source: "",
|
source: "",
|
||||||
state: this.hass.states[statisticId],
|
state: this.hass.states[statisticId],
|
||||||
issues: issues[statisticId],
|
issues: issues[statisticId],
|
||||||
|
@ -135,7 +135,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends LitElement {
|
|||||||
} else {
|
} else {
|
||||||
const data =
|
const data =
|
||||||
this._stats5min.length >= 2 ? this._stats5min : this._statsHour;
|
this._stats5min.length >= 2 ? this._stats5min : this._statsHour;
|
||||||
const unit = this._params!.statistic.unit_of_measurement;
|
const unit = this._params!.statistic.display_unit_of_measurement;
|
||||||
const rows: TemplateResult[] = [];
|
const rows: TemplateResult[] = [];
|
||||||
for (let i = 1; i < data.length; i++) {
|
for (let i = 1; i < data.length; i++) {
|
||||||
const stat = data[i];
|
const stat = data[i];
|
||||||
@ -221,7 +221,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends LitElement {
|
|||||||
label="New Value"
|
label="New Value"
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.selector=${this._amountSelector(
|
.selector=${this._amountSelector(
|
||||||
this._params!.statistic.unit_of_measurement
|
this._params!.statistic.display_unit_of_measurement
|
||||||
)}
|
)}
|
||||||
.value=${this._amount}
|
.value=${this._amount}
|
||||||
.disabled=${this._busy}
|
.disabled=${this._busy}
|
||||||
|
@ -315,11 +315,8 @@ class HuiEnergyDistrubutionCard
|
|||||||
${formatNumber(gasUsage || 0, this.hass.locale, {
|
${formatNumber(gasUsage || 0, this.hass.locale, {
|
||||||
maximumFractionDigits: 1,
|
maximumFractionDigits: 1,
|
||||||
})}
|
})}
|
||||||
${getEnergyGasUnit(
|
${getEnergyGasUnit(prefs, this._data.statsMetadata) ||
|
||||||
this.hass,
|
"m³"}
|
||||||
prefs,
|
|
||||||
this._data.statsMetadata
|
|
||||||
) || "m³"}
|
|
||||||
</div>
|
</div>
|
||||||
<svg width="80" height="30">
|
<svg width="80" height="30">
|
||||||
<path d="M40 0 v30" id="gas" />
|
<path d="M40 0 v30" id="gas" />
|
||||||
|
@ -274,8 +274,7 @@ export class HuiEnergyGasGraphCard
|
|||||||
) as GasSourceTypeEnergyPreference[];
|
) as GasSourceTypeEnergyPreference[];
|
||||||
|
|
||||||
this._unit =
|
this._unit =
|
||||||
getEnergyGasUnit(this.hass, energyData.prefs, energyData.statsMetadata) ||
|
getEnergyGasUnit(energyData.prefs, energyData.statsMetadata) || "m³";
|
||||||
"m³";
|
|
||||||
|
|
||||||
const datasets: ChartDataset<"bar", ScatterDataPoint[]>[] = [];
|
const datasets: ChartDataset<"bar", ScatterDataPoint[]>[] = [];
|
||||||
|
|
||||||
|
@ -131,8 +131,7 @@ export class HuiEnergySourcesTableCard
|
|||||||
);
|
);
|
||||||
|
|
||||||
const gasUnit =
|
const gasUnit =
|
||||||
getEnergyGasUnit(this.hass, this._data.prefs, this._data.statsMetadata) ||
|
getEnergyGasUnit(this._data.prefs, this._data.statsMetadata) || "";
|
||||||
"";
|
|
||||||
|
|
||||||
const compare = this._data.statsCompare !== undefined;
|
const compare = this._data.statsCompare !== undefined;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user