From 32ac04ea78463068dc025ec34adc9ad65d281b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20H=C3=B6rsken?= Date: Tue, 26 Oct 2021 12:18:26 +0200 Subject: [PATCH] Add support for hiding current weather in forecast card (#10267) --- .../cards/hui-weather-forecast-card.ts | 147 ++++++++++-------- src/panels/lovelace/cards/types.ts | 1 + .../hui-weather-forecast-card-editor.ts | 92 +++++++++-- src/translations/en.json | 4 +- 4 files changed, 168 insertions(+), 76 deletions(-) diff --git a/src/panels/lovelace/cards/hui-weather-forecast-card.ts b/src/panels/lovelace/cards/hui-weather-forecast-card.ts index a22b2c3a3a..0d599a383a 100644 --- a/src/panels/lovelace/cards/hui-weather-forecast-card.ts +++ b/src/panels/lovelace/cards/hui-weather-forecast-card.ts @@ -87,7 +87,14 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { } public getCardSize(): number { - return this._config?.show_forecast !== false ? 5 : 2; + let cardSize = 0; + if (this._config?.show_current !== false) { + cardSize += 2; + } + if (this._config?.show_forecast !== false) { + cardSize += 3; + } + return cardSize; } public setConfig(config: WeatherForecastCardConfig): void { @@ -168,6 +175,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { stateObj.attributes.forecast?.length ? stateObj.attributes.forecast.slice(0, this._veryVeryNarrow ? 3 : 5) : undefined; + const weather = !forecast || this._config?.show_current !== false; let hourly: boolean | undefined; let dayNight: boolean | undefined; @@ -202,74 +210,81 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { hasAction(this._config.tap_action) ? "0" : undefined )} > -
-
- ${weatherStateIcon || - html` - - `} -
-
-
-
- ${computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale - )} -
-
${name}
-
-
-
- ${formatNumber( - stateObj.attributes.temperature, - this.hass.locale - )} ${getWeatherUnit(this.hass, "temperature")} -
-
- ${this._config.secondary_info_attribute !== undefined - ? html` - ${this._config.secondary_info_attribute in - weatherAttrIcons + ${weather + ? html` +
+
+ ${weatherStateIcon || + html` + + `} +
+
+
+
+ ${computeStateDisplay( + this.hass.localize, + stateObj, + this.hass.locale + )} +
+
${name}
+
+
+
+ ${formatNumber( + stateObj.attributes.temperature, + this.hass.locale + )} ${getWeatherUnit(this.hass, "temperature")} +
+
+ ${this._config.secondary_info_attribute !== undefined ? html` - + ${this._config.secondary_info_attribute in + weatherAttrIcons + ? html` + + ` + : this.hass!.localize( + `ui.card.weather.attributes.${this._config.secondary_info_attribute}` + )} + ${this._config.secondary_info_attribute === + "wind_speed" + ? getWind( + this.hass, + stateObj.attributes.wind_speed, + stateObj.attributes.wind_bearing + ) + : html` + ${formatNumber( + stateObj.attributes[ + this._config.secondary_info_attribute + ], + this.hass.locale + )} + ${getWeatherUnit( + this.hass, + this._config.secondary_info_attribute + )} + `} ` - : this.hass!.localize( - `ui.card.weather.attributes.${this._config.secondary_info_attribute}` - )} - ${this._config.secondary_info_attribute === "wind_speed" - ? getWind( - this.hass, - stateObj.attributes.wind_speed, - stateObj.attributes.wind_bearing - ) - : html` - ${formatNumber( - stateObj.attributes[ - this._config.secondary_info_attribute - ], - this.hass.locale - )} - ${getWeatherUnit( - this.hass, - this._config.secondary_info_attribute - )} - `} - ` - : getSecondaryWeatherAttribute(this.hass, stateObj)} + : getSecondaryWeatherAttribute(this.hass, stateObj)} +
+
+
-
-
-
+ ` + : ""} ${forecast ? html`
diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts index ac4c4d6289..80a70b4378 100644 --- a/src/panels/lovelace/cards/types.ts +++ b/src/panels/lovelace/cards/types.ts @@ -387,6 +387,7 @@ export interface ThermostatCardConfig extends LovelaceCardConfig { export interface WeatherForecastCardConfig extends LovelaceCardConfig { entity: string; name?: string; + show_current?: boolean; show_forecast?: boolean; secondary_info_attribute?: string; theme?: string; diff --git a/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts index 38ccd48d12..106010c441 100644 --- a/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts @@ -6,7 +6,7 @@ import { computeRTLDirection } from "../../../../common/util/compute_rtl"; import "../../../../components/entity/ha-entity-attribute-picker"; import "../../../../components/entity/ha-entity-picker"; import "../../../../components/ha-formfield"; -import "../../../../components/ha-switch"; +import "../../../../components/ha-radio"; import { HomeAssistant } from "../../../../types"; import { WeatherForecastCardConfig } from "../../cards/types"; import "../../components/hui-theme-select-editor"; @@ -15,6 +15,8 @@ import { actionConfigStruct } from "../structs/action-struct"; import { EditorTarget, EntitiesEditorEvent } from "../types"; import { configElementStyle } from "./config-elements-style"; import { baseLovelaceCardConfig } from "../structs/base-card-struct"; +import { UNAVAILABLE } from "../../../../data/entity"; +import { WeatherEntity } from "../../../../data/weather"; const cardConfigStruct = assign( baseLovelaceCardConfig, @@ -22,6 +24,7 @@ const cardConfigStruct = assign( entity: optional(string()), name: optional(string()), theme: optional(string()), + show_current: optional(boolean()), show_forecast: optional(boolean()), secondary_info_attribute: optional(string()), tap_action: optional(actionConfigStruct), @@ -44,6 +47,18 @@ export class HuiWeatherForecastCardEditor public setConfig(config: WeatherForecastCardConfig): void { assert(config, cardConfigStruct); this._config = config; + + if ( + /* cannot show forecast in case it is unavailable on the entity */ + (config.show_forecast === true && this._has_forecast === false) || + /* cannot hide both weather and forecast, need one of them */ + (config.show_current === false && config.show_forecast === false) + ) { + /* reset to sane default, show weather, but hide forecast */ + fireEvent(this, "config-changed", { + config: { ...config, show_current: true, show_forecast: false }, + }); + } } get _entity(): string { @@ -58,14 +73,28 @@ export class HuiWeatherForecastCardEditor return this._config!.theme || ""; } + get _show_current(): boolean { + return this._config!.show_current ?? true; + } + get _show_forecast(): boolean { - return this._config!.show_forecast || true; + return this._config!.show_forecast ?? this._has_forecast === true; } get _secondary_info_attribute(): string { return this._config!.secondary_info_attribute || ""; } + get _has_forecast(): boolean | undefined { + if (this.hass && this._config) { + const stateObj = this.hass.states[this._config.entity] as WeatherEntity; + if (stateObj && stateObj.state !== UNAVAILABLE) { + return !!stateObj.attributes.forecast?.length; + } + } + return undefined; + } + protected render(): TemplateResult { if (!this.hass || !this._config) { return html``; @@ -103,8 +132,6 @@ export class HuiWeatherForecastCardEditor .configValue=${"theme"} @value-changed=${this._valueChanged} > -
-
+
+
- + + + +
@@ -143,7 +204,20 @@ export class HuiWeatherForecastCardEditor return; } if (target.configValue) { - if (target.value === "") { + if (target.configValue.startsWith("show_")) { + this._config = { ...this._config }; + if (target.configValue === "show_both") { + /* delete since true is default */ + delete this._config.show_current; + delete this._config.show_forecast; + } else if (target.configValue === "show_current") { + delete this._config.show_current; + this._config.show_forecast = false; + } else if (target.configValue === "show_forecast") { + delete this._config.show_forecast; + this._config.show_current = false; + } + } else if (target.value === "") { this._config = { ...this._config }; delete this._config[target.configValue!]; } else { diff --git a/src/translations/en.json b/src/translations/en.json index f52bdd62a2..e431546104 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3433,7 +3433,9 @@ "weather-forecast": { "name": "Weather Forecast", "description": "The Weather Forecast card displays the weather. Very useful to include on interfaces that people display on the wall.", - "show_forecast": "Show Forecast" + "show_both": "Show current Weather and Forecast", + "show_only_current": "Show only current Weather", + "show_only_forecast": "Show only Forecast" } }, "view": {