Save preferred energy period in localStorage (#24654)

This commit is contained in:
karwosts 2025-03-16 23:36:31 -07:00 committed by GitHub
parent 05aa55bfb9
commit 02fce1f40a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 196 additions and 359 deletions

View File

@ -0,0 +1,116 @@
import {
addDays,
subHours,
endOfDay,
endOfMonth,
endOfWeek,
endOfYear,
startOfDay,
startOfMonth,
startOfWeek,
startOfYear,
startOfQuarter,
endOfQuarter,
subDays,
subMonths,
} from "date-fns";
import type { HomeAssistant } from "../../types";
import { calcDate } from "./calc_date";
import { firstWeekdayIndex } from "./first_weekday";
export type DateRange =
| "today"
| "yesterday"
| "this_week"
| "this_month"
| "this_quarter"
| "this_year"
| "now-7d"
| "now-30d"
| "now-12m"
| "now-1h"
| "now-12h"
| "now-24h";
export const calcDateRange = (
hass: HomeAssistant,
range: DateRange
): [Date, Date] => {
const today = new Date();
const weekStartsOn = firstWeekdayIndex(hass.locale);
switch (range) {
case "today":
return [
calcDate(today, startOfDay, hass.locale, hass.config, {
weekStartsOn,
}),
calcDate(today, endOfDay, hass.locale, hass.config, {
weekStartsOn,
}),
];
case "yesterday":
return [
calcDate(addDays(today, -1), startOfDay, hass.locale, hass.config, {
weekStartsOn,
}),
calcDate(addDays(today, -1), endOfDay, hass.locale, hass.config, {
weekStartsOn,
}),
];
case "this_week":
return [
calcDate(today, startOfWeek, hass.locale, hass.config, {
weekStartsOn,
}),
calcDate(today, endOfWeek, hass.locale, hass.config, {
weekStartsOn,
}),
];
case "this_month":
return [
calcDate(today, startOfMonth, hass.locale, hass.config),
calcDate(today, endOfMonth, hass.locale, hass.config),
];
case "this_quarter":
return [
calcDate(today, startOfQuarter, hass.locale, hass.config),
calcDate(today, endOfQuarter, hass.locale, hass.config),
];
case "this_year":
return [
calcDate(today, startOfYear, hass.locale, hass.config),
calcDate(today, endOfYear, hass.locale, hass.config),
];
case "now-7d":
return [
calcDate(today, subDays, hass.locale, hass.config, 7),
calcDate(today, subDays, hass.locale, hass.config, 1),
];
case "now-30d":
return [
calcDate(today, subDays, hass.locale, hass.config, 30),
calcDate(today, subDays, hass.locale, hass.config, 1),
];
case "now-12m":
return [
calcDate(subMonths(today, 12), startOfMonth, hass.locale, hass.config),
calcDate(subMonths(today, 1), endOfMonth, hass.locale, hass.config),
];
case "now-1h":
return [
calcDate(today, subHours, hass.locale, hass.config, 1),
calcDate(today, subHours, hass.locale, hass.config, 0),
];
case "now-12h":
return [
calcDate(today, subHours, hass.locale, hass.config, 12),
calcDate(today, subHours, hass.locale, hass.config, 0),
];
case "now-24h":
return [
calcDate(today, subHours, hass.locale, hass.config, 24),
calcDate(today, subHours, hass.locale, hass.config, 0),
];
}
return [today, today];
};

View File

@ -3,25 +3,13 @@ import "@material/mwc-list/mwc-list";
import type { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
import "@material/mwc-list/mwc-list-item";
import { mdiCalendar } from "@mdi/js";
import {
addDays,
subHours,
endOfDay,
endOfMonth,
endOfWeek,
endOfYear,
startOfDay,
startOfMonth,
startOfWeek,
startOfYear,
isThisYear,
} from "date-fns";
import { isThisYear } from "date-fns";
import { fromZonedTime, toZonedTime } from "date-fns-tz";
import type { PropertyValues, TemplateResult } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import { calcDate, shiftDateRange } from "../common/datetime/calc_date";
import { shiftDateRange } from "../common/datetime/calc_date";
import { firstWeekdayIndex } from "../common/datetime/first_weekday";
import {
formatShortDateTime,
@ -36,9 +24,28 @@ import "./ha-icon-button";
import "./ha-icon-button-next";
import "./ha-icon-button-prev";
import "./ha-textarea";
import { calcDateRange } from "../common/datetime/calc_date_range";
import type { DateRange } from "../common/datetime/calc_date_range";
export type DateRangePickerRanges = Record<string, [Date, Date]>;
declare global {
interface HASSDomEvents {
"preset-selected": { index: number };
}
}
const RANGE_KEYS: DateRange[] = ["today", "yesterday", "this_week"];
const EXTENDED_RANGE_KEYS: DateRange[] = [
"this_month",
"this_year",
"now-1h",
"now-12h",
"now-24h",
"now-7d",
"now-30d",
];
@customElement("ha-date-range-picker")
export class HaDateRangePicker extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -84,194 +91,16 @@ export class HaDateRangePicker extends LitElement {
(changedProps.has("hass") &&
this.hass?.localize !== changedProps.get("hass")?.localize)
) {
const today = new Date();
const weekStartsOn = firstWeekdayIndex(this.hass.locale);
const weekStart = calcDate(
today,
startOfWeek,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
);
const weekEnd = calcDate(
today,
endOfWeek,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
);
const rangeKeys = this.extendedPresets
? [...RANGE_KEYS, ...EXTENDED_RANGE_KEYS]
: RANGE_KEYS;
this._ranges = {
[this.hass.localize("ui.components.date-range-picker.ranges.today")]: [
calcDate(today, startOfDay, this.hass.locale, this.hass.config, {
weekStartsOn,
}),
calcDate(today, endOfDay, this.hass.locale, this.hass.config, {
weekStartsOn,
}),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.yesterday"
)]: [
calcDate(
addDays(today, -1),
startOfDay,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
),
calcDate(
addDays(today, -1),
endOfDay,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.this_week"
)]: [weekStart, weekEnd],
...(this.extendedPresets
? {
[this.hass.localize(
"ui.components.date-range-picker.ranges.this_month"
)]: [
calcDate(
today,
startOfMonth,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
),
calcDate(
today,
endOfMonth,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.this_year"
)]: [
calcDate(
today,
startOfYear,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
),
calcDate(today, endOfYear, this.hass.locale, this.hass.config, {
weekStartsOn,
}),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.now-1h"
)]: [
calcDate(
today,
subHours,
this.hass.locale,
this.hass.config,
1
),
calcDate(
today,
subHours,
this.hass.locale,
this.hass.config,
0
),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.now-12h"
)]: [
calcDate(
today,
subHours,
this.hass.locale,
this.hass.config,
12
),
calcDate(
today,
subHours,
this.hass.locale,
this.hass.config,
0
),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.now-24h"
)]: [
calcDate(
today,
subHours,
this.hass.locale,
this.hass.config,
24
),
calcDate(
today,
subHours,
this.hass.locale,
this.hass.config,
0
),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.now-7d"
)]: [
calcDate(
today,
subHours,
this.hass.locale,
this.hass.config,
24 * 7
),
calcDate(
today,
subHours,
this.hass.locale,
this.hass.config,
0
),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.now-30d"
)]: [
calcDate(
today,
subHours,
this.hass.locale,
this.hass.config,
24 * 30
),
calcDate(
today,
subHours,
this.hass.locale,
this.hass.config,
0
),
],
}
: {}),
};
this._ranges = {};
rangeKeys.forEach((key) => {
this._ranges![
this.hass.localize(`ui.components.date-range-picker.ranges.${key}`)
] = calcDateRange(this.hass, key);
});
}
}
@ -410,6 +239,10 @@ export class HaDateRangePicker extends LitElement {
const dateRange = Object.values(this.ranges || this._ranges!)[
ev.detail.index
];
fireEvent(this, "preset-selected", {
index: ev.detail.index,
});
const dateRangePicker = this._dateRangePicker;
dateRangePicker.clickRange(dateRange);
dateRangePicker.clickedApply();

View File

@ -27,6 +27,8 @@ import type {
StatisticsUnitConfiguration,
} from "./recorder";
import { fetchStatistics, getStatisticMetadata } from "./recorder";
import { calcDateRange } from "../common/datetime/calc_date_range";
import type { DateRange } from "../common/datetime/calc_date_range";
const energyCollectionKeys: (string | undefined)[] = [];
@ -665,21 +667,17 @@ export const getEnergyDataCollection = (
collection._active = 0;
collection.prefs = options.prefs;
const now = new Date();
const hour = formatTime24h(now, hass.locale, hass.config).split(":")[0];
// Set start to start of today if we have data for today, otherwise yesterday
collection.start = calcDate(
hour === "0" ? addDays(now, -1) : now,
startOfDay,
hass.locale,
hass.config
);
collection.end = calcDate(
hour === "0" ? addDays(now, -1) : now,
endOfDay,
hass.locale,
hass.config
);
const preferredPeriod =
(localStorage.getItem(`energy-default-period-${key}`) as DateRange) ||
"today";
const period =
preferredPeriod === "today" && hour === "0" ? "yesterday" : preferredPeriod;
[collection.start, collection.end] = calcDateRange(hass, period);
const scheduleUpdatePeriod = () => {
collection._updatePeriodTimeout = window.setTimeout(

View File

@ -5,20 +5,13 @@ import {
differenceInDays,
differenceInMonths,
endOfDay,
endOfMonth,
endOfQuarter,
endOfToday,
endOfWeek,
endOfYear,
isFirstDayOfMonth,
isLastDayOfMonth,
startOfDay,
startOfMonth,
startOfQuarter,
startOfWeek,
startOfYear,
subDays,
subMonths,
} from "date-fns";
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import type { PropertyValues } from "lit";
@ -50,6 +43,20 @@ import type { EnergyData } from "../../../data/energy";
import { getEnergyDataCollection } from "../../../data/energy";
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import type { HomeAssistant } from "../../../types";
import { calcDateRange } from "../../../common/datetime/calc_date_range";
import type { DateRange } from "../../../common/datetime/calc_date_range";
const RANGE_KEYS: DateRange[] = [
"today",
"yesterday",
"this_week",
"this_month",
"this_quarter",
"this_year",
"now-7d",
"now-30d",
"now-12m",
];
@customElement("hui-energy-period-selector")
export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
@ -117,94 +124,13 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
(changedProps.has("hass") &&
this.hass?.localize !== changedProps.get("hass")?.localize)
) {
const today = new Date();
const weekStartsOn = firstWeekdayIndex(this.hass.locale);
// pre defined date ranges
this._ranges = {
[this.hass.localize("ui.components.date-range-picker.ranges.today")]: [
calcDate(today, startOfDay, this.hass.locale, this.hass.config, {
weekStartsOn,
}),
calcDate(today, endOfDay, this.hass.locale, this.hass.config, {
weekStartsOn,
}),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.yesterday"
)]: [
calcDate(
calcDate(today, subDays, this.hass.locale, this.hass.config, 1),
startOfDay,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
),
calcDate(
calcDate(today, subDays, this.hass.locale, this.hass.config, 1),
endOfDay,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.this_week"
)]: [
calcDate(today, startOfWeek, this.hass.locale, this.hass.config, {
weekStartsOn,
}),
calcDate(today, endOfWeek, this.hass.locale, this.hass.config, {
weekStartsOn,
}),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.this_month"
)]: [
calcDate(today, startOfMonth, this.hass.locale, this.hass.config),
calcDate(today, endOfMonth, this.hass.locale, this.hass.config),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.this_quarter"
)]: [
calcDate(today, startOfQuarter, this.hass.locale, this.hass.config),
calcDate(today, endOfQuarter, this.hass.locale, this.hass.config),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.this_year"
)]: [
calcDate(today, startOfYear, this.hass.locale, this.hass.config),
calcDate(today, endOfYear, this.hass.locale, this.hass.config),
],
[this.hass.localize("ui.components.date-range-picker.ranges.now-7d")]: [
calcDate(today, subDays, this.hass.locale, this.hass.config, 7),
calcDate(today, subDays, this.hass.locale, this.hass.config, 1),
],
[this.hass.localize("ui.components.date-range-picker.ranges.now-30d")]:
[
calcDate(today, subDays, this.hass.locale, this.hass.config, 30),
calcDate(today, subDays, this.hass.locale, this.hass.config, 1),
],
[this.hass.localize("ui.components.date-range-picker.ranges.now-12m")]:
[
calcDate(
subMonths(today, 12),
startOfMonth,
this.hass.locale,
this.hass.config
),
calcDate(
subMonths(today, 1),
endOfMonth,
this.hass.locale,
this.hass.config
),
],
};
this._ranges = {};
RANGE_KEYS.forEach((key) => {
this._ranges[
this.hass.localize(`ui.components.date-range-picker.ranges.${key}`)
] = calcDateRange(this.hass, key);
});
}
}
@ -272,6 +198,7 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
.endDate=${this._endDate || new Date()}
.ranges=${this._ranges}
@value-changed=${this._dateRangeChanged}
@preset-selected=${this._presetSelected}
minimal
header-position
></ha-date-range-picker>
@ -393,6 +320,13 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
this._updateCollectionPeriod();
}
private _presetSelected(ev) {
localStorage.setItem(
`energy-default-period-_${this.collectionKey || "energy"}`,
RANGE_KEYS[ev.detail.index]
);
}
private _pickNow() {
if (!this._startDate) return;
@ -404,44 +338,14 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
);
const today = new Date();
if (range === "month") {
this._startDate = calcDate(
today,
startOfMonth,
this.hass.locale,
this.hass.config
);
this._endDate = calcDate(
today,
endOfMonth,
this.hass.locale,
this.hass.config
);
[this._startDate, this._endDate] = calcDateRange(this.hass, "this_month");
} else if (range === "quarter") {
this._startDate = calcDate(
today,
startOfQuarter,
this.hass.locale,
this.hass.config
);
this._endDate = calcDate(
today,
endOfQuarter,
this.hass.locale,
this.hass.config
[this._startDate, this._endDate] = calcDateRange(
this.hass,
"this_quarter"
);
} else if (range === "year") {
this._startDate = calcDate(
today,
startOfYear,
this.hass.locale,
this.hass.config
);
this._endDate = calcDate(
today,
endOfYear,
this.hass.locale,
this.hass.config
);
[this._startDate, this._endDate] = calcDateRange(this.hass, "this_year");
} else {
const weekStartsOn = firstWeekdayIndex(this.hass.locale);
const weekStart = calcDate(
@ -469,23 +373,9 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
this._endDate!.getTime() === weekEnd.getTime()
) {
// Pick current week
this._startDate = calcDate(
today,
startOfWeek,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
);
this._endDate = calcDate(
today,
endOfWeek,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
[this._startDate, this._endDate] = calcDateRange(
this.hass,
"this_week"
);
} else {
// Custom date range