diff --git a/src/panels/calendar/ha-panel-calendar.ts b/src/panels/calendar/ha-panel-calendar.ts index 0ab80ec3aa09..190968f63350 100644 --- a/src/panels/calendar/ha-panel-calendar.ts +++ b/src/panels/calendar/ha-panel-calendar.ts @@ -61,6 +61,11 @@ class PanelCalendar extends LitElement { private _headerHeight = 56; + private _refreshInterval?: number; + + // Refresh interval in milliseconds (5 minutes) + private static readonly REFRESH_INTERVAL_MS = 5 * 60 * 1000; + public connectedCallback() { super.connectedCallback(); this._mql = window.matchMedia( @@ -72,12 +77,14 @@ class PanelCalendar extends LitElement { this._headerHeight = Number( computedStyles.getPropertyValue("--header-height").replace("px", "") ); + this._startRefreshInterval(); } public disconnectedCallback() { super.disconnectedCallback(); this._mql?.removeListener(this._setIsMobile!); this._mql = undefined; + this._stopRefreshInterval(); } private _setIsMobile = (ev: MediaQueryListEvent) => { @@ -89,6 +96,20 @@ class PanelCalendar extends LitElement { if (!this.hasUpdated) { this._calendars = getCalendars(this.hass); } + + // Refresh calendar events if any of the calendar entities' states have changed + if (changedProps.has("hass") && this.hasUpdated) { + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if (oldHass) { + const calendarStateChanged = this._calendars.some( + (cal) => + oldHass.states[cal.entity_id] !== this.hass.states[cal.entity_id] + ); + if (calendarStateChanged) { + this._handleRefresh(); + } + } + } } protected render(): TemplateResult { @@ -290,6 +311,20 @@ class PanelCalendar extends LitElement { } } + private _startRefreshInterval(): void { + this._stopRefreshInterval(); + this._refreshInterval = window.setInterval(() => { + this._handleRefresh(); + }, PanelCalendar.REFRESH_INTERVAL_MS); + } + + private _stopRefreshInterval(): void { + if (this._refreshInterval !== undefined) { + clearInterval(this._refreshInterval); + this._refreshInterval = undefined; + } + } + static get styles(): CSSResultGroup { return [ haStyle, diff --git a/src/panels/lovelace/cards/hui-calendar-card.ts b/src/panels/lovelace/cards/hui-calendar-card.ts index adea17966b6d..1861672af2ae 100644 --- a/src/panels/lovelace/cards/hui-calendar-card.ts +++ b/src/panels/lovelace/cards/hui-calendar-card.ts @@ -73,6 +73,11 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { private _resizeObserver?: ResizeObserver; + private _refreshInterval?: number; + + // Refresh interval in milliseconds (5 minutes) + private static readonly REFRESH_INTERVAL_MS = 5 * 60 * 1000; + public setConfig(config: CalendarCardConfig): void { if (!config.entities?.length) { throw new Error("Entities must be specified"); @@ -110,6 +115,7 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { public connectedCallback(): void { super.connectedCallback(); this.updateComplete.then(() => this._attachObserver()); + this._startRefreshInterval(); } public disconnectedCallback(): void { @@ -117,6 +123,7 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { if (this._resizeObserver) { this._resizeObserver.disconnect(); } + this._stopRefreshInterval(); } protected render() { @@ -170,6 +177,17 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { ) { applyThemesOnElement(this, this.hass.themes, this._config!.theme); } + + // Refresh calendar events if any of the calendar entities' states have changed + if (changedProps.has("hass") && oldHass) { + const calendarStateChanged = this._calendars.some( + (cal) => + oldHass.states[cal.entity_id] !== this.hass!.states[cal.entity_id] + ); + if (calendarStateChanged) { + this._fetchCalendarEvents(); + } + } } private _handleViewChanged(ev: HASSDomEvent): void { @@ -223,6 +241,20 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { this._resizeObserver.observe(card); } + private _startRefreshInterval(): void { + this._stopRefreshInterval(); + this._refreshInterval = window.setInterval(() => { + this._fetchCalendarEvents(); + }, HuiCalendarCard.REFRESH_INTERVAL_MS); + } + + private _stopRefreshInterval(): void { + if (this._refreshInterval !== undefined) { + clearInterval(this._refreshInterval); + this._refreshInterval = undefined; + } + } + static styles = css` ha-card { position: relative;