Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 59 additions & 5 deletions src/data/energy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {
addDays,
addHours,
addMilliseconds,
addMonths,
differenceInDays,
endOfToday,
endOfYesterday,
Expand All @@ -14,9 +17,9 @@ import { ConfigEntry, getConfigEntries } from "./config_entries";
import { subscribeEntityRegistry } from "./entity_registry";
import {
fetchStatistics,
getStatisticMetadata,
Statistics,
StatisticsMetaData,
getStatisticMetadata,
} from "./history";

const energyCollectionKeys: (string | undefined)[] = [];
Expand Down Expand Up @@ -232,19 +235,24 @@ export const energySourcesByType = (prefs: EnergyPreferences) =>
export interface EnergyData {
start: Date;
end?: Date;
startCompare?: Date;
endCompare?: Date;
prefs: EnergyPreferences;
info: EnergyInfo;
stats: Statistics;
statsCompare: Statistics;
co2SignalConfigEntry?: ConfigEntry;
co2SignalEntity?: string;
fossilEnergyConsumption?: FossilEnergyConsumption;
fossilEnergyConsumptionCompare?: FossilEnergyConsumption;
}

const getEnergyData = async (
hass: HomeAssistant,
prefs: EnergyPreferences,
start: Date,
end?: Date
end?: Date,
compare?: boolean
): Promise<EnergyData> => {
const [configEntries, entityRegistryEntries, info] = await Promise.all([
getConfigEntries(hass, { domain: "co2signal" }),
Expand Down Expand Up @@ -350,6 +358,8 @@ const getEnergyData = async (
}

const dayDifference = differenceInDays(end || new Date(), start);
const period =
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😬


// Subtract 1 hour from start to get starting point data
const startMinHour = addHours(start, -1);
Expand All @@ -359,10 +369,34 @@ const getEnergyData = async (
startMinHour,
end,
statIDs,
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour"
period
);

let statsCompare;
let startCompare;
let endCompare;
if (compare) {
if (dayDifference > 27 && dayDifference < 32) {
// When comparing a month, we want to start at the begining of the month
startCompare = addMonths(start, -1);
} else {
startCompare = addDays(start, (dayDifference + 1) * -1);
}

const compareStartMinHour = addHours(startCompare, -1);
endCompare = addMilliseconds(start, -1);

statsCompare = await fetchStatistics(
hass!,
compareStartMinHour,
endCompare,
statIDs,
period
);
}

let fossilEnergyConsumption: FossilEnergyConsumption | undefined;
let fossilEnergyConsumptionCompare: FossilEnergyConsumption | undefined;

if (co2SignalEntity !== undefined) {
fossilEnergyConsumption = await getFossilEnergyConsumption(
Expand All @@ -373,6 +407,16 @@ const getEnergyData = async (
end,
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour"
);
if (compare) {
fossilEnergyConsumptionCompare = await getFossilEnergyConsumption(
hass!,
startCompare,
consumptionStatIDs,
co2SignalEntity,
endCompare,
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour"
);
}
}

Object.values(stats).forEach((stat) => {
Expand All @@ -388,15 +432,19 @@ const getEnergyData = async (
}
});

const data = {
const data: EnergyData = {
start,
end,
startCompare,
endCompare,
info,
prefs,
stats,
statsCompare,
co2SignalConfigEntry,
co2SignalEntity,
fossilEnergyConsumption,
fossilEnergyConsumptionCompare,
};

return data;
Expand All @@ -405,9 +453,11 @@ const getEnergyData = async (
export interface EnergyCollection extends Collection<EnergyData> {
start: Date;
end?: Date;
compare?: boolean;
prefs?: EnergyPreferences;
clearPrefs(): void;
setPeriod(newStart: Date, newEnd?: Date): void;
setCompare(compare: boolean): void;
_refreshTimeout?: number;
_updatePeriodTimeout?: number;
_active: number;
Expand Down Expand Up @@ -478,7 +528,8 @@ export const getEnergyDataCollection = (
hass,
collection.prefs,
collection.start,
collection.end
collection.end,
collection.compare
);
}
) as EnergyCollection;
Expand Down Expand Up @@ -534,6 +585,9 @@ export const getEnergyDataCollection = (
collection._updatePeriodTimeout = undefined;
}
};
collection.setCompare = (compare: boolean) => {
collection.compare = compare;
};
return collection;
};

Expand Down
39 changes: 33 additions & 6 deletions src/panels/energy/ha-panel-energy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import "@polymer/app-layout/app-header/app-header";
import "@polymer/app-layout/app-toolbar/app-toolbar";
import "@material/mwc-tab";
import "@material/mwc-tab-bar";
import { mdiDotsVertical } from "@mdi/js";
import "@polymer/app-layout/app-header/app-header";
import "@polymer/app-layout/app-toolbar/app-toolbar";
import {
css,
CSSResultGroup,
Expand All @@ -12,14 +13,16 @@ import {
} from "lit";
import { customElement, property, state } from "lit/decorators";
import "../../components/ha-menu-button";
import "../../components/ha-button-menu";
import "../../components/ha-check-list-item";
import { LovelaceConfig } from "../../data/lovelace";
import "../../layouts/ha-app-layout";

import { haStyle } from "../../resources/styles";
import "../lovelace/views/hui-view";
import { HomeAssistant } from "../../types";
import { Lovelace } from "../lovelace/types";
import { LovelaceConfig } from "../../data/lovelace";
import "../lovelace/components/hui-energy-period-selector";
import { Lovelace } from "../lovelace/types";
import "../lovelace/views/hui-view";
import { getEnergyDataCollection } from "../../data/energy";

const LOVELACE_CONFIG: LovelaceConfig = {
views: [
Expand All @@ -41,6 +44,8 @@ class PanelEnergy extends LitElement {

@state() private _lovelace?: Lovelace;

@state() private _compare = false;

public willUpdate(changedProps: PropertyValues) {
if (!this.hasUpdated) {
this.hass.loadFragmentTranslation("lovelace");
Expand Down Expand Up @@ -81,6 +86,19 @@ class PanelEnergy extends LitElement {
collectionKey="energy_dashboard"
></hui-energy-period-selector>
`}
<ha-button-menu

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this a button, "COMPARE DATA" maybe as label? Or this icon
image

corner="BOTTOM_START"
@action=${this._toggleCompare}
>
<ha-icon-button
.label=${this.hass.localize("panel.menu")}
.path=${mdiDotsVertical}
slot="trigger"
></ha-icon-button>
<ha-check-list-item left .selected=${this._compare}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's show this as a "comparing mode enabled" bar in the UI at the top. Probably ha-alert?

Compare with previous period
</ha-check-list-item>
</ha-button-menu>
</app-toolbar>
</app-header>
<hui-view
Expand Down Expand Up @@ -118,6 +136,15 @@ class PanelEnergy extends LitElement {
};
}

private _toggleCompare() {
this._compare = !this._compare;
const energyCollection = getEnergyDataCollection(this.hass, {
key: "energy_dashboard",
});
energyCollection.setCompare(this._compare);
energyCollection.refresh();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only need to refresh if compare is now true and it's not loaded for current period yet?

}

static get styles(): CSSResultGroup {
return [
haStyle,
Expand Down
Loading