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

Fix energy date selection grid #21292

Closed
wants to merge 2 commits into from
Closed
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: 1 addition & 1 deletion src/data/timer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const computeDisplayTimer = (
return hass.formatEntityState(stateObj);
}

let display = secondsToDuration(timeRemaining || 0);
let display = secondsToDuration(timeRemaining || 0) || "0";

if (stateObj.state === "paused") {
display = `${display} (${hass.formatEntityState(stateObj)})`;
Expand Down
26 changes: 20 additions & 6 deletions src/panels/lovelace/cards/energy/hui-energy-date-selection-card.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import {
html,
LitElement,
nothing,
css,
CSSResultGroup,
LitElement,
PropertyValues,
css,
html,
nothing,
} from "lit";
import { customElement, property, state } from "lit/decorators";
import { HomeAssistant } from "../../../../types";
import { hasConfigChanged } from "../../common/has-changed";
import "../../components/hui-energy-period-selector";
import { LovelaceCard } from "../../types";
import { LovelaceCard, LovelaceLayoutOptions } from "../../types";
import { EnergyCardBaseConfig } from "../types";
import { hasConfigChanged } from "../../common/has-changed";

@customElement("hui-energy-date-selection-card")
export class HuiEnergyDateSelectionCard
Expand All @@ -26,6 +26,13 @@ export class HuiEnergyDateSelectionCard
return 1;
}

public getLayoutOptions(): LovelaceLayoutOptions {
return {
grid_rows: 1,
grid_columns: 4,
};
}

public setConfig(config: EnergyCardBaseConfig): void {
this._config = config;
}
Expand Down Expand Up @@ -57,6 +64,13 @@ export class HuiEnergyDateSelectionCard

static get styles(): CSSResultGroup {
return css`
:host {
ha-card {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.padded {
padding-left: 16px !important;
padding-inline-start: 16px !important;
Expand Down
17 changes: 13 additions & 4 deletions src/panels/lovelace/cards/hui-tile-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,19 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
}

if (domain === "update") {
return html`${computeUpdateStateDisplay(
stateObj as UpdateEntity,
this.hass!
)}`;
return html`
${computeUpdateStateDisplay(stateObj as UpdateEntity, this.hass!)}
`;
}

if (domain === "timer") {
import("../../../state-display/state-display-timer");
return html`
<state-display-timer
.hass=${this.hass}
.stateObj=${stateObj}
></state-display-timer>
`;
}

return this._renderStateContent(stateObj, "state");
Expand Down
87 changes: 6 additions & 81 deletions src/panels/lovelace/entity-rows/hui-timer-entity-row.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { HassEntity } from "home-assistant-js-websocket";
import { html, LitElement, PropertyValues, nothing } from "lit";
import { LitElement, PropertyValues, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { computeDisplayTimer, timerTimeRemaining } from "../../../data/timer";
import "../../../state-display/state-display-timer";
import { HomeAssistant } from "../../../types";
import { hasConfigOrEntityChanged } from "../common/has-changed";
import "../components/hui-generic-entity-row";
Expand All @@ -14,42 +13,11 @@ class HuiTimerEntityRow extends LitElement {

@state() private _config?: EntityConfig;

@state() private _timeRemaining?: number;

private _interval?: number;

public setConfig(config: EntityConfig): void {
if (!config) {
throw new Error("Invalid configuration");
}
this._config = config;

if (!this.hass) {
return;
}

const stateObj = this.hass!.states[this._config.entity];

if (stateObj) {
this._startInterval(stateObj);
} else {
this._clearInterval();
}
}

public disconnectedCallback(): void {
super.disconnectedCallback();
this._clearInterval();
}

public connectedCallback(): void {
super.connectedCallback();
if (this._config && this._config.entity) {
const stateObj = this.hass?.states[this._config!.entity];
if (stateObj) {
this._startInterval(stateObj);
}
}
}

protected render() {
Expand All @@ -70,61 +38,18 @@ class HuiTimerEntityRow extends LitElement {
return html`
<hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
<div class="text-content">
${computeDisplayTimer(this.hass, stateObj, this._timeRemaining)}
<state-display-timer
.hass=${this.hass}
.stateObj=${stateObj}
></state-display-timer>
</div>
</hui-generic-entity-row>
`;
}

protected shouldUpdate(changedProps: PropertyValues): boolean {
if (changedProps.has("_timeRemaining")) {
return true;
}

return hasConfigOrEntityChanged(this, changedProps);
}

protected updated(changedProps: PropertyValues) {
super.updated(changedProps);

if (!this._config || !changedProps.has("hass")) {
return;
}
const stateObj = this.hass!.states[this._config!.entity];
const oldHass = changedProps.get("hass") as this["hass"];
const oldStateObj = oldHass
? oldHass.states[this._config!.entity]
: undefined;

if (oldStateObj !== stateObj) {
this._startInterval(stateObj);
} else if (!stateObj) {
this._clearInterval();
}
}

private _clearInterval(): void {
if (this._interval) {
window.clearInterval(this._interval);
this._interval = undefined;
}
}

private _startInterval(stateObj: HassEntity): void {
this._clearInterval();
this._calculateRemaining(stateObj);

if (stateObj.state === "active") {
this._interval = window.setInterval(
() => this._calculateRemaining(stateObj),
1000
);
}
}

private _calculateRemaining(stateObj: HassEntity): void {
this._timeRemaining = timerTimeRemaining(stateObj);
}
}

declare global {
Expand Down
74 changes: 74 additions & 0 deletions src/state-display/state-display-timer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type { HassEntity } from "home-assistant-js-websocket";
import { PropertyValues, ReactiveElement } from "lit";
import { customElement, property, state } from "lit/decorators";
import { computeDisplayTimer, timerTimeRemaining } from "../data/timer";
import type { HomeAssistant } from "../types";

@customElement("state-display-timer")
class StateDisplayTimer extends ReactiveElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@property({ attribute: false }) public stateObj!: HassEntity;

@state() private timeRemaining?: number;

private _updateRemaining: any;

protected createRenderRoot() {
return this;
}

protected update(changedProps: PropertyValues) {
super.update(changedProps);
this.innerHTML =
computeDisplayTimer(this.hass, this.stateObj, this.timeRemaining) ?? "-";
}

connectedCallback() {
super.connectedCallback();
if (this.stateObj) {
this._startInterval(this.stateObj);
}
}

disconnectedCallback() {
super.disconnectedCallback();
this._clearInterval();
}

protected willUpdate(changedProp: PropertyValues): void {
super.willUpdate(changedProp);
if (changedProp.has("stateObj")) {
this._startInterval(this.stateObj);
}
}

private _clearInterval() {
if (this._updateRemaining) {
clearInterval(this._updateRemaining);
this._updateRemaining = null;
}
}

private _startInterval(stateObj: HassEntity) {
this._clearInterval();
this._calculateRemaining(stateObj);

if (stateObj.state === "active") {
this._updateRemaining = setInterval(
() => this._calculateRemaining(this.stateObj),
1000
);
}
}

private _calculateRemaining(stateObj: HassEntity) {
this.timeRemaining = timerTimeRemaining(stateObj);
}
}

declare global {
interface HTMLElementTagNameMap {
"state-display-timer": StateDisplayTimer;
}
}
67 changes: 7 additions & 60 deletions src/state-summary/state-card-timer.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
import type { HassEntity } from "home-assistant-js-websocket";
import {
css,
CSSResultGroup,
html,
LitElement,
PropertyValues,
TemplateResult,
} from "lit";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import "../components/entity/state-info";
import { computeDisplayTimer, timerTimeRemaining } from "../data/timer";
import { HomeAssistant } from "../types";
import { haStyle } from "../resources/styles";
import "../state-display/state-display-timer";
import { HomeAssistant } from "../types";

@customElement("state-card-timer")
class StateCardTimer extends LitElement {
Expand All @@ -21,10 +14,6 @@ class StateCardTimer extends LitElement {

@property({ type: Boolean }) public inDialog = false;

@property({ type: Number }) public timeRemaining?: number;

private _updateRemaining: any;

protected render(): TemplateResult {
return html`
<div class="horizontal justified layout">
Expand All @@ -34,63 +23,21 @@ class StateCardTimer extends LitElement {
.inDialog=${this.inDialog}
></state-info>
<div class="state">
${this._displayState(this.timeRemaining, this.stateObj)}
<state-display-timer
.hass=${this.hass}
.stateObj=${this.stateObj}
></state-display-timer>
</div>
</div>
`;
}

connectedCallback() {
super.connectedCallback();
this._startInterval(this.stateObj);
}

disconnectedCallback() {
super.disconnectedCallback();
this._clearInterval();
}

protected willUpdate(changedProp: PropertyValues): void {
super.willUpdate(changedProp);
if (changedProp.has("stateObj")) {
this._startInterval(this.stateObj);
}
}

private _clearInterval() {
if (this._updateRemaining) {
clearInterval(this._updateRemaining);
this._updateRemaining = null;
}
}

private _startInterval(stateObj) {
this._clearInterval();
this._calculateRemaining(stateObj);

if (stateObj.state === "active") {
this._updateRemaining = setInterval(
() => this._calculateRemaining(this.stateObj),
1000
);
}
}

private _calculateRemaining(stateObj) {
this.timeRemaining = timerTimeRemaining(stateObj);
}

private _displayState(timeRemaining, stateObj) {
return computeDisplayTimer(this.hass, stateObj, timeRemaining);
}

static get styles(): CSSResultGroup {
return [
haStyle,
css`
.state {
color: var(--primary-text-color);

margin-left: 16px;
margin-inline-start: 16px;
margin-inline-end: initial;
Expand Down
Loading