From f9b06adc9f9a20e66efa2b612262fae9f78e2bde Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 28 Oct 2018 20:07:05 +0100 Subject: [PATCH 1/4] Handle no operation mode (#1901) * Handle no operation mode * Upgrade HAWS so we can use correct types * Lint --- package.json | 2 +- .../lovelace/cards/hui-thermostat-card.ts | 32 ++++++++++++------- src/types.ts | 26 +++++++++++++++ yarn.lock | 8 ++--- 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 9e1794b488..a6af340147 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "es6-object-assign": "^1.1.0", "eslint-import-resolver-webpack": "^0.10.1", "fecha": "^2.3.3", - "home-assistant-js-websocket": "^3.1.4", + "home-assistant-js-websocket": "^3.1.5", "intl-messageformat": "^2.2.0", "jquery": "^3.3.1", "js-yaml": "^3.12.0", diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index bf066ed007..a8ce3badfd 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -6,7 +6,7 @@ import "../../../components/ha-card.js"; import "../../../components/ha-icon.js"; import { roundSliderStyle } from "../../../resources/jquery.roundslider"; -import { HomeAssistant } from "../../../types.js"; +import { HomeAssistant, ClimateEntity } from "../../../types.js"; import { hassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin"; import { LovelaceCard, LovelaceConfig } from "../types.js"; import computeStateName from "../../../common/entity/compute_state_name.js"; @@ -65,10 +65,10 @@ export class HuiThermostatCard extends hassLocalizeLitMixin(LitElement) if (!this.hass || !this.config) { return html``; } - const stateObj = this.hass.states[this.config.entity]; + const stateObj = this.hass.states[this.config.entity] as ClimateEntity; const broadCard = this.clientWidth > 390; - const mode = modeIcons[stateObj.attributes.operation_mode] - ? stateObj.attributes.operation_mode + const mode = modeIcons[stateObj.attributes.operation_mode || ""] + ? stateObj.attributes.operation_mode! : "unknown-mode"; return html` ${this.renderStyle()} @@ -97,7 +97,7 @@ export class HuiThermostatCard extends hassLocalizeLitMixin(LitElement) `state.climate.${stateObj.state}` )}
- ${stateObj.attributes.operation_list.map((modeItem) => + ${(stateObj.attributes.operation_list || []).map((modeItem) => this._renderIcon(modeItem, mode) )}
@@ -118,7 +118,7 @@ export class HuiThermostatCard extends hassLocalizeLitMixin(LitElement) } protected firstUpdated() { - const stateObj = this.hass!.states[this.config!.entity]; + const stateObj = this.hass!.states[this.config!.entity] as ClimateEntity; const _sliderType = stateObj.attributes.target_temp_low && @@ -138,16 +138,24 @@ export class HuiThermostatCard extends hassLocalizeLitMixin(LitElement) } protected updated() { - const attrs = this.hass!.states[this.config!.entity].attributes; + const stateObj = this.hass!.states[this.config!.entity] as ClimateEntity; let sliderValue; let uiValue; - if (attrs.target_temp_low && attrs.target_temp_high) { - sliderValue = `${attrs.target_temp_low}, ${attrs.target_temp_high}`; - uiValue = formatTemp([attrs.target_temp_low, attrs.target_temp_high]); + if ( + stateObj.attributes.target_temp_low && + stateObj.attributes.target_temp_high + ) { + sliderValue = `${stateObj.attributes.target_temp_low}, ${ + stateObj.attributes.target_temp_high + }`; + uiValue = formatTemp([ + stateObj.attributes.target_temp_low, + stateObj.attributes.target_temp_high, + ]); } else { - sliderValue = uiValue = attrs.temperature; + sliderValue = uiValue = stateObj.attributes.temperature; } jQuery("#thermostat", this.shadowRoot).roundSlider({ @@ -307,7 +315,7 @@ export class HuiThermostatCard extends hassLocalizeLitMixin(LitElement) } private _setTemperature(e) { - const stateObj = this.hass!.states[this.config!.entity]; + const stateObj = this.hass!.states[this.config!.entity] as ClimateEntity; if ( stateObj.attributes.target_temp_low && stateObj.attributes.target_temp_high diff --git a/src/types.ts b/src/types.ts index 632f07d82d..359425876a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,6 +4,8 @@ import { Auth, Connection, MessageBase, + HassEntityBase, + HassEntityAttributeBase, } from "home-assistant-js-websocket"; export interface Credential { @@ -85,3 +87,27 @@ export interface HomeAssistant { sendWS: (msg: MessageBase) => Promise; callWS: (msg: MessageBase) => Promise; } + +export type ClimateEntity = HassEntityBase & { + attributes: HassEntityAttributeBase & { + current_temperature: number; + min_temp: number; + max_temp: number; + temperature: number; + target_temp_step?: number; + target_temp_high?: number; + target_temp_low?: number; + target_humidity?: number; + target_humidity_low?: number; + target_humidity_high?: number; + fan_mode?: string; + fan_list?: string[]; + operation_mode?: string; + operation_list?: string[]; + hold_mode?: string; + swing_mode?: string; + swing_list?: string[]; + away_mode?: "on" | "off"; + aux_heat?: "on" | "off"; + }; +}; diff --git a/yarn.lock b/yarn.lock index 6b32265093..acec776d59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8114,10 +8114,10 @@ hoek@4.x.x: resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA== -home-assistant-js-websocket@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/home-assistant-js-websocket/-/home-assistant-js-websocket-3.1.4.tgz#4ff338a51d272650db96cd5c67aa05878ef234a4" - integrity sha512-lkAglJ04ja98awHPqI09On8v1wHr0/QmjLYlPGC6LWF7HBMAtYMasQ2mPEb5nLLZrD0DroxNVQK2owlRy3+NOQ== +home-assistant-js-websocket@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/home-assistant-js-websocket/-/home-assistant-js-websocket-3.1.5.tgz#56358660bbccb5f24e16f9197bbad12739f9b756" + integrity sha512-BlANSkA9ob6wlUJCYS26n1tfMla+aJzB2rhhXSFi0iiTtWWfuOlcSOw8pxjeWhh1I9oAcbQ4qxhB7Np1EXG+Og== home-or-tmp@^2.0.0: version "2.0.0" From d591c45e4d5bddfb661731025cbd78127d56a7ff Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 30 Oct 2018 08:38:27 +0100 Subject: [PATCH 2/4] Propagate hass correctly (#1918) --- .../lovelace/cards/hui-entities-card.ts | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/panels/lovelace/cards/hui-entities-card.ts b/src/panels/lovelace/cards/hui-entities-card.ts index 32cc353d7d..a16dde376d 100644 --- a/src/panels/lovelace/cards/hui-entities-card.ts +++ b/src/panels/lovelace/cards/hui-entities-card.ts @@ -1,4 +1,10 @@ -import { html, LitElement, PropertyDeclarations } from "@polymer/lit-element"; +import { + html, + LitElement, + PropertyDeclarations, + PropertyValues, +} from "@polymer/lit-element"; +import { TemplateResult } from "lit-html"; import "../../../components/ha-card.js"; import "../components/hui-entities-toggle.js"; @@ -34,13 +40,19 @@ class HuiEntitiesCard extends hassLocalizeLitMixin(LitElement) protected _config?: Config; protected _configEntities?: ConfigEntity[]; - set hass(hass) { + set hass(hass: HomeAssistant) { this._hass = hass; - this.shadowRoot!.querySelectorAll("#states > *").forEach( + this.shadowRoot!.querySelectorAll("#states > div > *").forEach( (element: unknown) => { (element as EntityRow).hass = hass; } ); + const entitiesToggle = this.shadowRoot!.querySelector( + "hui-entities-toggle" + ); + if (entitiesToggle) { + (entitiesToggle as any).hass = hass; + } } static get properties(): PropertyDeclarations { @@ -49,7 +61,7 @@ class HuiEntitiesCard extends hassLocalizeLitMixin(LitElement) }; } - public getCardSize() { + public getCardSize(): number { if (!this._config) { return 0; } @@ -57,7 +69,7 @@ class HuiEntitiesCard extends hassLocalizeLitMixin(LitElement) return (this._config.title ? 1 : 0) + this._config.entities.length; } - public setConfig(config: Config) { + public setConfig(config: Config): void { const entities = processConfigEntities(config.entities); for (const entity of entities) { if ( @@ -81,7 +93,13 @@ class HuiEntitiesCard extends hassLocalizeLitMixin(LitElement) this._configEntities = entities; } - protected render() { + protected updated(_changedProperties: PropertyValues): void { + if (this._hass && this._config) { + applyThemesOnElement(this, this._hass.themes, this._config.theme); + } + } + + protected render(): TemplateResult { if (!this._config || !this._hass) { return html``; } @@ -105,8 +123,7 @@ class HuiEntitiesCard extends hassLocalizeLitMixin(LitElement) .entities="${this._configEntities!.map( (conf) => conf.entity )}" - > - ` + >` } ` } @@ -119,7 +136,7 @@ class HuiEntitiesCard extends hassLocalizeLitMixin(LitElement) `; } - private renderStyle() { + private renderStyle(): TemplateResult { return html`