Improve handling of units in energy dashboard (#13454)

This commit is contained in:
Erik Montnemery 2022-08-31 11:30:50 +02:00 committed by GitHub
parent 9b2dcbdb59
commit 1e19799da9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 68 additions and 51 deletions

View File

@ -243,8 +243,8 @@ class StatisticsChart extends LitElement {
if (!this.unit) {
if (unit === undefined) {
unit = meta?.unit_of_measurement;
} else if (unit !== meta?.unit_of_measurement) {
unit = meta?.display_unit_of_measurement;
} else if (unit !== meta?.display_unit_of_measurement) {
unit = null;
}
}

View File

@ -31,12 +31,23 @@ export class HaStatisticPicker extends LitElement {
@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}
* @attr include-unit-of-measurement
* @attr include-statistics-unit-of-measurement
*/
@property({ type: Array, attribute: "include-unit-of-measurement" })
public includeUnitOfMeasurement?: string[];
@property({
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.
@ -86,7 +97,8 @@ export class HaStatisticPicker extends LitElement {
private _getStatistics = memoizeOne(
(
statisticIds: StatisticsMetaData[],
includeUnitOfMeasurement?: string[],
includeStatisticsUnitOfMeasurement?: string[],
includeDisplayUnitOfMeasurement?: string[],
includeDeviceClasses?: string[],
entitiesOnly?: boolean
): Array<{ id: string; name: string; state?: HassEntity }> => {
@ -101,9 +113,18 @@ export class HaStatisticPicker extends LitElement {
];
}
if (includeUnitOfMeasurement) {
if (includeStatisticsUnitOfMeasurement) {
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) {
(this.comboBox as any).items = this._getStatistics(
this.statisticIds!,
this.includeUnitOfMeasurement,
this.includeStatisticsUnitOfMeasurement,
this.includeDisplayUnitOfMeasurement,
this.includeDeviceClasses,
this.entitiesOnly
);
@ -192,7 +214,8 @@ export class HaStatisticPicker extends LitElement {
this.updateComplete.then(() => {
(this.comboBox as any).items = this._getStatistics(
this.statisticIds!,
this.includeUnitOfMeasurement,
this.includeStatisticsUnitOfMeasurement,
this.includeDisplayUnitOfMeasurement,
this.includeDeviceClasses,
this.entitiesOnly
);

View File

@ -597,7 +597,7 @@ export const getEnergySolarForecasts = (hass: HomeAssistant) =>
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_UNITS = [
...ENERGY_GAS_VOLUME_UNITS,
@ -607,18 +607,21 @@ export const ENERGY_GAS_UNITS = [
export type EnergyGasUnit = "volume" | "energy";
export const getEnergyGasUnitCategory = (
hass: HomeAssistant,
prefs: EnergyPreferences
prefs: EnergyPreferences,
statisticsMetaData: Record<string, StatisticsMetaData> = {},
excludeSource?: string
): EnergyGasUnit | undefined => {
for (const source of prefs.energy_sources) {
if (source.type !== "gas") {
continue;
}
const entity = hass.states[source.stat_energy_from];
if (entity) {
if (excludeSource && excludeSource === source.stat_energy_from) {
continue;
}
const statisticIdWithMeta = statisticsMetaData[source.stat_energy_from];
if (statisticIdWithMeta) {
return ENERGY_GAS_VOLUME_UNITS.includes(
entity.attributes.unit_of_measurement!
statisticIdWithMeta.display_unit_of_measurement
)
? "volume"
: "energy";
@ -628,7 +631,6 @@ export const getEnergyGasUnitCategory = (
};
export const getEnergyGasUnit = (
hass: HomeAssistant,
prefs: EnergyPreferences,
statisticsMetaData: Record<string, StatisticsMetaData> = {}
): string | undefined => {
@ -636,18 +638,9 @@ export const getEnergyGasUnit = (
if (source.type !== "gas") {
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];
if (statisticIdWithMeta?.unit_of_measurement) {
return statisticIdWithMeta.unit_of_measurement === "Wh"
? "kWh"
: statisticIdWithMeta.unit_of_measurement;
if (statisticIdWithMeta?.display_unit_of_measurement) {
return statisticIdWithMeta.display_unit_of_measurement;
}
}
return undefined;

View File

@ -82,7 +82,8 @@ export interface StatisticValue {
}
export interface StatisticsMetaData {
unit_of_measurement: string;
display_unit_of_measurement: string;
statistics_unit_of_measurement: string;
statistic_id: string;
source: string;
name?: string | null;

View File

@ -133,7 +133,7 @@ export class EnergyGasSettings extends LitElement {
private _addSource() {
showEnergySettingsGasDialog(this, {
unit: getEnergyGasUnitCategory(this.hass, this.preferences),
unit: getEnergyGasUnitCategory(this.preferences, this.statsMetadata),
saveCallback: async (source) => {
delete source.unit_of_measurement;
await this._savePreferences({
@ -149,7 +149,11 @@ export class EnergyGasSettings extends LitElement {
ev.currentTarget.closest(".row").source;
showEnergySettingsGasDialog(this, {
source: { ...origSource },
unit: getEnergyGasUnitCategory(this.hass, this.preferences),
unit: getEnergyGasUnitCategory(
this.preferences,
this.statsMetadata,
origSource.stat_energy_from
),
saveCallback: async (newSource) => {
await this._savePreferences({
...this.preferences,

View File

@ -67,7 +67,7 @@ export class DialogEnergyBatterySettings
<ha-statistic-picker
.hass=${this.hass}
.includeUnitOfMeasurement=${energyUnits}
.includeStatisticsUnitOfMeasurement=${energyUnits}
.includeDeviceClasses=${energyDeviceClasses}
.value=${this._source.stat_energy_to}
.label=${this.hass.localize(
@ -79,7 +79,7 @@ export class DialogEnergyBatterySettings
<ha-statistic-picker
.hass=${this.hass}
.includeUnitOfMeasurement=${energyUnits}
.includeStatisticsUnitOfMeasurement=${energyUnits}
.includeDeviceClasses=${energyDeviceClasses}
.value=${this._source.stat_energy_from}
.label=${this.hass.localize(

View File

@ -69,7 +69,7 @@ export class DialogEnergyDeviceSettings
<ha-statistic-picker
.hass=${this.hass}
.includeUnitOfMeasurement=${energyUnits}
.includeStatisticsUnitOfMeasurement=${energyUnits}
.includeDeviceClasses=${energyDeviceClasses}
.label=${this.hass.localize(
"ui.panel.config.energy.device_consumption.dialog.device_consumption_energy"

View File

@ -90,7 +90,7 @@ export class DialogEnergyGasSettings
<ha-statistic-picker
.hass=${this.hass}
.includeUnitOfMeasurement=${this._params.unit === undefined
.includeStatisticsUnitOfMeasurement=${this._params.unit === undefined
? ENERGY_GAS_UNITS
: this._params.unit === "energy"
? ENERGY_GAS_ENERGY_UNITS

View File

@ -93,7 +93,7 @@ export class DialogEnergyGridFlowSettings
<ha-statistic-picker
.hass=${this.hass}
.includeUnitOfMeasurement=${energyUnits}
.includeStatisticsUnitOfMeasurement=${energyUnits}
.includeDeviceClasses=${energyDeviceClasses}
.value=${this._source[
this._params.direction === "from"

View File

@ -79,7 +79,7 @@ export class DialogEnergySolarSettings
<ha-statistic-picker
.hass=${this.hass}
.includeUnitOfMeasurement=${energyUnits}
.includeStatisticsUnitOfMeasurement=${energyUnits}
.includeDeviceClasses=${energyDeviceClasses}
.value=${this._source.stat_energy_from}
.label=${this.hass.localize(

View File

@ -211,7 +211,8 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
) {
this._data.push({
statistic_id: statisticId,
unit_of_measurement: "",
statistics_unit_of_measurement: "",
display_unit_of_measurement: "",
source: "",
state: this.hass.states[statisticId],
issues: issues[statisticId],

View File

@ -135,7 +135,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends LitElement {
} else {
const data =
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[] = [];
for (let i = 1; i < data.length; i++) {
const stat = data[i];
@ -221,7 +221,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends LitElement {
label="New Value"
.hass=${this.hass}
.selector=${this._amountSelector(
this._params!.statistic.unit_of_measurement
this._params!.statistic.display_unit_of_measurement
)}
.value=${this._amount}
.disabled=${this._busy}

View File

@ -315,11 +315,8 @@ class HuiEnergyDistrubutionCard
${formatNumber(gasUsage || 0, this.hass.locale, {
maximumFractionDigits: 1,
})}
${getEnergyGasUnit(
this.hass,
prefs,
this._data.statsMetadata
) || "m³"}
${getEnergyGasUnit(prefs, this._data.statsMetadata) ||
"m³"}
</div>
<svg width="80" height="30">
<path d="M40 0 v30" id="gas" />

View File

@ -274,8 +274,7 @@ export class HuiEnergyGasGraphCard
) as GasSourceTypeEnergyPreference[];
this._unit =
getEnergyGasUnit(this.hass, energyData.prefs, energyData.statsMetadata) ||
"m³";
getEnergyGasUnit(energyData.prefs, energyData.statsMetadata) || "m³";
const datasets: ChartDataset<"bar", ScatterDataPoint[]>[] = [];

View File

@ -131,8 +131,7 @@ export class HuiEnergySourcesTableCard
);
const gasUnit =
getEnergyGasUnit(this.hass, this._data.prefs, this._data.statsMetadata) ||
"";
getEnergyGasUnit(this._data.prefs, this._data.statsMetadata) || "";
const compare = this._data.statsCompare !== undefined;