Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for rolling & default periods #33

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ The UI Editor looks like this:
| prev_next_buttons | `boolean` | true | If set to `true`, buttons will be added to control the previous and next period. |
| compare_button_type | `string` | undefined | If set, a button will be added to toggle the compare mode. Supported values are `icon` and `text`. |
| period_buttons | `array` | undefined | If set, only buttons inside this array will be displayed. Supported values are `day`, `week`, `month`, `year` and `custom`. Order of your array will be applied. |
| default_period | `string` | `day` | Period that will be pre-selected upon loading page. Supported values are `day`, `week`, `month`, and `year`. Respects the state of `rolling_periods`. |
| rolling_periods | `boolean` | false | If set to `true`, Today will refer to the _past_ e.g. day (last 24 hours), otherwise it refers to the _current_ e.g. day (starting from midnight). |
| custom_period_label | `string` | undefined | If set, the label of the custom period button will be changed to this value. Otherwise will be synced to your HA language (If not, consider submitting a PR, adding your language to the localize function.) |


Expand Down
109 changes: 74 additions & 35 deletions src/energy-period-selector-plus-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { mdiCompare, mdiCompareRemove, mdiCalendarTodayOutline } from '@mdi/js';
import {
addDays,
addMilliseconds,
addMonths,
addWeeks,
addYears,
Expand Down Expand Up @@ -56,9 +57,15 @@ export class EnergyPeriodSelectorBase extends SubscribeMixin(LitElement) {
}

public hassSubscribe(): UnsubscribeFunc[] {
this._period = this._config?.default_period || 'day';
const startDate = this._beginningOfPeriod(new Date());
const endDate = this._endOfPeriod(startDate);

return [
getEnergyDataCollection(this.hass, {
key: this.collectionKey,
start: startDate,
end: endDate,
}).subscribe(data => this._updateDates(data)),
];
}
Expand Down Expand Up @@ -147,12 +154,14 @@ export class EnergyPeriodSelectorBase extends SubscribeMixin(LitElement) {
? dateRangePicker
: html`
<div class="label">
${this._period === 'day'
${this._period === 'day' && !this._config?.rolling_periods
? formatDate(this._startDate, this.hass.locale)
: this._period === 'month'
: this._period === 'month' && !this._config?.rolling_periods
? formatDateMonthYear(this._startDate, this.hass.locale)
: this._period === 'year'
: this._period === 'year' && !this._config?.rolling_periods
? formatDateYear(this._startDate, this.hass.locale)
: this._period === 'year'
? `${formatDateMonthYear(this._startDate, this.hass.locale)} – ${formatDateMonthYear(this._endDate || new Date(), this.hass.locale)}`
: `${formatDateShort(this._startDate, this.hass.locale)} – ${formatDateShort(this._endDate || new Date(), this.hass.locale)}`}
${this._config?.prev_next_buttons !== false
? html`
Expand Down Expand Up @@ -216,39 +225,82 @@ export class EnergyPeriodSelectorBase extends SubscribeMixin(LitElement) {
start: this._startDate,
end: this._endDate || endOfToday(),
})
? today
? this._config?.rolling_periods
? new Date()
: today
: this._startDate;

const weekStartsOn = firstWeekdayIndex(this.hass.locale);

this._setDate(
this._period === 'day'
? startOfDay(start)
: this._period === 'week'
? startOfWeek(start, { weekStartsOn })
: this._period === 'month'
? startOfMonth(start)
: this._period === 'year'
? startOfYear(start)
: this._startDate || startOfToday(),
this._beginningOfPeriod(start),
this._period === 'custom' ? this._endDate : undefined,
);
}

private _pickToday() {
private _beginningOfPeriod(start: Date): Date {
const weekStartsOn = firstWeekdayIndex(this.hass.locale);

this._setDate(
return this._config?.rolling_periods
? addMilliseconds(
this._period === 'day'
? startOfToday()
: this._period === 'week'
? startOfWeek(new Date(), { weekStartsOn })
: this._period === 'month'
? startOfMonth(new Date())
: startOfYear(new Date()),
? addDays(start, -1)
: this._period === 'week'
? addWeeks(start, -1)
: this._period === 'month'
? addMonths(start, -1)
: this._period === 'year'
? addYears(start, -1)
: start
, 1) : (
this._period === 'day'
? startOfToday()
: this._period === 'week'
? startOfWeek(start, { weekStartsOn })
: this._period === 'month'
? startOfMonth(start)
: this._period === 'year'
? startOfYear(start)
: start
);
}

private _endOfPeriod(startDate: Date, customEndDate?: Date): Date {
const weekStartsOn = firstWeekdayIndex(this.hass.locale);

return this._config?.rolling_periods
? addMilliseconds(
this._period === 'day'
? addDays(startDate!, 1)
: this._period === 'week'
? addWeeks(startDate!, 1)
: this._period === 'month'
? addMonths(startDate!, 1)
: this._period === 'year'
? addYears(startDate!, 1)
: this._period === 'custom' && customEndDate
? endOfDay(customEndDate)
: this._endDate || endOfToday()
, -1)
: (
this._period === 'day'
? endOfDay(startDate)
: this._period === 'week'
? endOfWeek(startDate, { weekStartsOn })
: this._period === 'month'
? endOfMonth(startDate)
: this._period === 'year'
? endOfYear(startDate)
: this._period === 'custom' && customEndDate
? endOfDay(customEndDate)
: this._endDate || endOfToday()
);
}

private _pickToday() {
this._setDate(this._beginningOfPeriod(new Date()));
}

private _pickPrevious() {
const newStart =
this._period === 'day'
Expand Down Expand Up @@ -278,20 +330,7 @@ export class EnergyPeriodSelectorBase extends SubscribeMixin(LitElement) {
}

private _setDate(startDate: Date, customEndDate?: Date) {
const weekStartsOn = firstWeekdayIndex(this.hass.locale);

const endDate: Date =
this._period === 'day'
? endOfDay(startDate)
: this._period === 'week'
? endOfWeek(startDate, { weekStartsOn })
: this._period === 'month'
? endOfMonth(startDate)
: this._period === 'year'
? endOfYear(startDate)
: this._period === 'custom' && customEndDate
? endOfDay(customEndDate)
: this._endDate || endOfToday();
const endDate: Date = this._endOfPeriod(startDate, customEndDate);

const energyCollection = getEnergyDataCollection(this.hass);
energyCollection.setPeriod(startDate, endDate);
Expand Down
2 changes: 2 additions & 0 deletions src/energy-period-selector-plus-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ export interface EnergyPeriodSelectorPlusConfig extends LovelaceCardConfig, Ener
compare_button_label?: string;
today_button_type?: string | boolean;
period_buttons?: string[];
default_period?: 'day' | 'week' | 'month' | 'year' | 'custom';
rolling_periods?: boolean;
custom_period_label?: string;
}
6 changes: 3 additions & 3 deletions src/energy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ const clearEnergyCollectionPreferences = (hass: HomeAssistant) => {
});
};

export const getEnergyDataCollection = (hass: HomeAssistant, options: { prefs?: EnergyPreferences; key?: string } = {}): EnergyCollection => {
export const getEnergyDataCollection = (hass: HomeAssistant, options: { prefs?: EnergyPreferences; key?: string; start?: Date, end?: Date } = {}): EnergyCollection => {
let key = '_energy';
if (options.key) {
if (!options.key.startsWith('energy_')) {
Expand Down Expand Up @@ -576,8 +576,8 @@ export const getEnergyDataCollection = (hass: HomeAssistant, options: { prefs?:
collection.prefs = options.prefs;
const now = new Date();
// Set start to start of today if we have data for today, otherwise yesterday
collection.start = now.getHours() > 0 ? startOfToday() : startOfYesterday();
collection.end = now.getHours() > 0 ? endOfToday() : endOfYesterday();
collection.start = options.start || (now.getHours() > 0 ? startOfToday() : startOfYesterday());
collection.end = options.end || (now.getHours() > 0 ? endOfToday() : endOfYesterday());

const scheduleUpdatePeriod = () => {
collection._updatePeriodTimeout = window.setTimeout(
Expand Down
2 changes: 2 additions & 0 deletions src/localize/languages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"text": "Text"
},
"period_buttons": "Zeitraumschaltflächen",
"default_period": "Standardzeitraum",
"rolling_periods": "Rollen Zeitraum",
"today_button_type": "Heutiger Schaltflächentyp",
"compare_button_label": "Beschriftung der Vergleichsschaltfläche",
"period_buttons_options": {
Expand Down
2 changes: 2 additions & 0 deletions src/localize/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"text": "Text"
},
"period_buttons": "Period Buttons",
"default_period": "Default Period",
"rolling_periods": "Rolling periods",
"today_button_type": "Today Button Type",
"compare_button_label": "Compare Button Label",
"period_buttons_options": {
Expand Down
2 changes: 2 additions & 0 deletions src/localize/languages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"text": "Texto"
},
"period_buttons": "Botones de período",
"default_period": "Período predeterminado",
"rolling_periods": "Periodos rodantes",
"today_button_type": "Tipo de botón Hoy",
"compare_button_label": "Etiqueta del botón de comparación",
"period_buttons_options": {
Expand Down
2 changes: 2 additions & 0 deletions src/localize/languages/pt-PT.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"text": "Texto"
},
"period_buttons": "Botões de Período",
"default_period": "Período padrão",
"rolling_periods": "Períodos contínuos",
"today_button_type": "Tipo de Botão Hoje",
"compare_button_label": "Rótulo do Botão Comparar",
"period_buttons_options": {
Expand Down
22 changes: 22 additions & 0 deletions src/ui-editor/ui-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export class EnergyPeriodSelectorEditor extends LitElement implements LovelaceCa
compare_button_type: optional(string()),
today_button_type: optional(any()),
period_buttons: optional(any()),
default_period: optional(any()),
rolling_periods: optional(any()),
custom_period_label: optional(string()),
compare_button_label: optional(string()),
}),
Expand Down Expand Up @@ -69,6 +71,10 @@ export class EnergyPeriodSelectorEditor extends LitElement implements LovelaceCa
name: 'prev_next_buttons',
selector: { boolean: {} },
},
{
name: 'rolling_periods',
selector: { boolean: {} },
},
],
},
{
Expand Down Expand Up @@ -111,6 +117,20 @@ export class EnergyPeriodSelectorEditor extends LitElement implements LovelaceCa
},
},
},
{
name: 'default_period',
selector: {
select: {
options: [
{ value: 'day', label: localize('editor.fields.period_buttons_options.day') },
{ value: 'week', label: localize('editor.fields.period_buttons_options.week') },
{ value: 'month', label: localize('editor.fields.period_buttons_options.month') },
{ value: 'year', label: localize('editor.fields.period_buttons_options.year') },
],
mode: 'dropdown',
},
},
},
{
type: 'grid',
name: '',
Expand Down Expand Up @@ -152,6 +172,8 @@ export class EnergyPeriodSelectorEditor extends LitElement implements LovelaceCa
compare_button_type: this._config.compare_button_type ?? '',
today_button_type: this._config.today_button_type ?? 'text',
period_buttons: this._config.period_buttons ?? ['day', 'week', 'month', 'year'],
default_period: this._config.default_period ?? 'day',
rolling_periods: this._config.rolling_periods ?? false,
};

const schema = this._schema(data.compare_button_type === 'text', data.period_buttons.includes('custom'));
Expand Down
Loading