diff --git a/src/components/entity/ha-entity-toggle.ts b/src/components/entity/ha-entity-toggle.ts
index 18caf31ea9..2b0c40c3c5 100644
--- a/src/components/entity/ha-entity-toggle.ts
+++ b/src/components/entity/ha-entity-toggle.ts
@@ -10,14 +10,19 @@ import {
CSSResult,
css,
property,
+ PropertyValues,
} from "lit-element";
import { HomeAssistant } from "../../types";
import { HassEntity } from "home-assistant-js-websocket";
+const isOn = (stateObj?: HassEntity) =>
+ stateObj !== undefined && !STATES_OFF.includes(stateObj.state);
+
class HaEntityToggle extends LitElement {
// hass is not a property so that we only re-render on stateObj changes
public hass?: HomeAssistant;
@property() public stateObj?: HassEntity;
+ @property() private _isOn: boolean = false;
protected render(): TemplateResult | void {
if (!this.stateObj) {
@@ -26,26 +31,24 @@ class HaEntityToggle extends LitElement {
`;
}
- const isOn = this._isOn;
-
if (this.stateObj.attributes.assumed_state) {
return html`
`;
}
return html`
`;
@@ -56,10 +59,10 @@ class HaEntityToggle extends LitElement {
this.addEventListener("click", (ev) => ev.stopPropagation());
}
- private get _isOn(): boolean {
- return (
- this.stateObj !== undefined && !STATES_OFF.includes(this.stateObj.state)
- );
+ protected updated(changedProps: PropertyValues): void {
+ if (changedProps.has("stateObj")) {
+ this._isOn = isOn(this.stateObj);
+ }
}
private _toggleChanged(ev) {
@@ -106,6 +109,9 @@ class HaEntityToggle extends LitElement {
const currentState = this.stateObj;
+ // Optimistic update.
+ this._isOn = turnOn;
+
await this.hass.callService(serviceDomain, service, {
entity_id: this.stateObj.entity_id,
});
@@ -113,18 +119,8 @@ class HaEntityToggle extends LitElement {
setTimeout(async () => {
// If after 2 seconds we have not received a state update
// reset the switch to it's original state.
- if (this.stateObj !== currentState) {
- return;
- }
- // 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;
+ if (this.stateObj === currentState) {
+ this._isOn = isOn(this.stateObj);
}
}, 2000);
}