Better fix for ha-entity-toggle (#2873)

This commit is contained in:
Paulus Schoutsen 2019-03-01 11:17:48 -08:00 committed by GitHub
parent 178e4de452
commit 9383d80354
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -10,14 +10,19 @@ import {
CSSResult, CSSResult,
css, css,
property, property,
PropertyValues,
} from "lit-element"; } from "lit-element";
import { HomeAssistant } from "../../types"; import { HomeAssistant } from "../../types";
import { HassEntity } from "home-assistant-js-websocket"; import { HassEntity } from "home-assistant-js-websocket";
const isOn = (stateObj?: HassEntity) =>
stateObj !== undefined && !STATES_OFF.includes(stateObj.state);
class HaEntityToggle extends LitElement { class HaEntityToggle extends LitElement {
// hass is not a property so that we only re-render on stateObj changes // hass is not a property so that we only re-render on stateObj changes
public hass?: HomeAssistant; public hass?: HomeAssistant;
@property() public stateObj?: HassEntity; @property() public stateObj?: HassEntity;
@property() private _isOn: boolean = false;
protected render(): TemplateResult | void { protected render(): TemplateResult | void {
if (!this.stateObj) { if (!this.stateObj) {
@ -26,26 +31,24 @@ class HaEntityToggle extends LitElement {
`; `;
} }
const isOn = this._isOn;
if (this.stateObj.attributes.assumed_state) { if (this.stateObj.attributes.assumed_state) {
return html` return html`
<paper-icon-button <paper-icon-button
icon="hass:flash-off" icon="hass:flash-off"
@click=${this._turnOff} @click=${this._turnOff}
?state-active=${!isOn} ?state-active=${!this._isOn}
></paper-icon-button> ></paper-icon-button>
<paper-icon-button <paper-icon-button
icon="hass:flash" icon="hass:flash"
@click=${this._turnOn} @click=${this._turnOn}
?state-active=${isOn} ?state-active=${this._isOn}
></paper-icon-button> ></paper-icon-button>
`; `;
} }
return html` return html`
<paper-toggle-button <paper-toggle-button
.checked=${isOn} .checked=${this._isOn}
@change=${this._toggleChanged} @change=${this._toggleChanged}
></paper-toggle-button> ></paper-toggle-button>
`; `;
@ -56,10 +59,10 @@ class HaEntityToggle extends LitElement {
this.addEventListener("click", (ev) => ev.stopPropagation()); this.addEventListener("click", (ev) => ev.stopPropagation());
} }
private get _isOn(): boolean { protected updated(changedProps: PropertyValues): void {
return ( if (changedProps.has("stateObj")) {
this.stateObj !== undefined && !STATES_OFF.includes(this.stateObj.state) this._isOn = isOn(this.stateObj);
); }
} }
private _toggleChanged(ev) { private _toggleChanged(ev) {
@ -106,6 +109,9 @@ class HaEntityToggle extends LitElement {
const currentState = this.stateObj; const currentState = this.stateObj;
// Optimistic update.
this._isOn = turnOn;
await this.hass.callService(serviceDomain, service, { await this.hass.callService(serviceDomain, service, {
entity_id: this.stateObj.entity_id, entity_id: this.stateObj.entity_id,
}); });
@ -113,18 +119,8 @@ class HaEntityToggle extends LitElement {
setTimeout(async () => { setTimeout(async () => {
// If after 2 seconds we have not received a state update // If after 2 seconds we have not received a state update
// reset the switch to it's original state. // reset the switch to it's original state.
if (this.stateObj !== currentState) { if (this.stateObj === currentState) {
return; this._isOn = isOn(this.stateObj);
}
// Force a re-render. It's not good enough to just call this.requestUpdate()
// because the value has changed outside of Lit's render function, and so Lit
// won't update the property again, because it's the same as last update.
// So we just temporarily unset the stateObj and set it again.
this.stateObj = undefined;
await this.updateComplete;
// Make sure that a stateObj was not set in between.
if (this.stateObj === undefined) {
this.stateObj = currentState;
} }
}, 2000); }, 2000);
} }