mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-26 14:27:20 +00:00
148 lines
3.8 KiB
TypeScript
148 lines
3.8 KiB
TypeScript
import { HassEntity } from "home-assistant-js-websocket";
|
|
import {
|
|
customElement,
|
|
html,
|
|
internalProperty,
|
|
LitElement,
|
|
property,
|
|
PropertyValues,
|
|
TemplateResult,
|
|
} from "lit-element";
|
|
import secondsToDuration from "../../../common/datetime/seconds_to_duration";
|
|
import { timerTimeRemaining } from "../../../common/entity/timer_time_remaining";
|
|
import { HomeAssistant } from "../../../types";
|
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
|
import "../components/hui-generic-entity-row";
|
|
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
|
import { EntityConfig } from "./types";
|
|
|
|
@customElement("hui-timer-entity-row")
|
|
class HuiTimerEntityRow extends LitElement {
|
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
|
|
|
@internalProperty() private _config?: EntityConfig;
|
|
|
|
@internalProperty() private _timeRemaining?: number;
|
|
|
|
private _interval?: number;
|
|
|
|
public setConfig(config: EntityConfig): void {
|
|
if (!config) {
|
|
throw new Error("Invalid configuration");
|
|
}
|
|
this._config = config;
|
|
}
|
|
|
|
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(): TemplateResult {
|
|
if (!this._config || !this.hass) {
|
|
return html``;
|
|
}
|
|
|
|
const stateObj = this.hass.states[this._config.entity];
|
|
|
|
if (!stateObj) {
|
|
return html`
|
|
<hui-warning>
|
|
${createEntityNotFoundWarning(this.hass, this._config.entity)}
|
|
</hui-warning>
|
|
`;
|
|
}
|
|
|
|
return html`
|
|
<hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
|
|
<div class="text-content">${this._computeDisplay(stateObj)}</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 (changedProps.has("hass")) {
|
|
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);
|
|
}
|
|
|
|
private _computeDisplay(stateObj: HassEntity): string | null {
|
|
if (!stateObj) {
|
|
return null;
|
|
}
|
|
|
|
if (stateObj.state === "idle" || this._timeRemaining === 0) {
|
|
return (
|
|
this.hass!.localize(`state.timer.${stateObj.state}`) || stateObj.state
|
|
);
|
|
}
|
|
|
|
let display = secondsToDuration(this._timeRemaining || 0);
|
|
|
|
if (stateObj.state === "paused") {
|
|
display += ` (${this.hass!.localize("state.timer.paused")})`;
|
|
}
|
|
|
|
return display;
|
|
}
|
|
}
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
"hui-timer-entity-row": HuiTimerEntityRow;
|
|
}
|
|
}
|