Add support for hiding current weather in forecast card (#10267)

This commit is contained in:
Marc Hörsken 2021-10-26 12:18:26 +02:00 committed by GitHub
parent 5d6bacb0bd
commit 32ac04ea78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 168 additions and 76 deletions

View File

@ -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
)}
>
<div class="content">
<div class="icon-image">
${weatherStateIcon ||
html`
<ha-state-icon
class="weather-icon"
.state=${stateObj}
></ha-state-icon>
`}
</div>
<div class="info">
<div class="name-state">
<div class="state">
${computeStateDisplay(
this.hass.localize,
stateObj,
this.hass.locale
)}
</div>
<div class="name" .title=${name}>${name}</div>
</div>
<div class="temp-attribute">
<div class="temp">
${formatNumber(
stateObj.attributes.temperature,
this.hass.locale
)}&nbsp;<span>${getWeatherUnit(this.hass, "temperature")}</span>
</div>
<div class="attribute">
${this._config.secondary_info_attribute !== undefined
? html`
${this._config.secondary_info_attribute in
weatherAttrIcons
${weather
? html`
<div class="content">
<div class="icon-image">
${weatherStateIcon ||
html`
<ha-state-icon
class="weather-icon"
.state=${stateObj}
></ha-state-icon>
`}
</div>
<div class="info">
<div class="name-state">
<div class="state">
${computeStateDisplay(
this.hass.localize,
stateObj,
this.hass.locale
)}
</div>
<div class="name" .title=${name}>${name}</div>
</div>
<div class="temp-attribute">
<div class="temp">
${formatNumber(
stateObj.attributes.temperature,
this.hass.locale
)}&nbsp;<span
>${getWeatherUnit(this.hass, "temperature")}</span
>
</div>
<div class="attribute">
${this._config.secondary_info_attribute !== undefined
? html`
<ha-svg-icon
class="attr-icon"
.path=${weatherAttrIcons[
this._config.secondary_info_attribute
]}
></ha-svg-icon>
${this._config.secondary_info_attribute in
weatherAttrIcons
? html`
<ha-svg-icon
class="attr-icon"
.path=${weatherAttrIcons[
this._config.secondary_info_attribute
]}
></ha-svg-icon>
`
: 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)}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`
: ""}
${forecast
? html`
<div class="forecast">

View File

@ -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;

View File

@ -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}
></hui-theme-select-editor>
</div>
<div class="side-by-side">
<ha-entity-attribute-picker
.hass=${this.hass}
.entityId=${this._entity}
@ -117,17 +144,51 @@ export class HuiWeatherForecastCardEditor
.configValue=${"secondary_info_attribute"}
@value-changed=${this._valueChanged}
></ha-entity-attribute-picker>
</div>
<div class="side-by-side">
<ha-formfield
.label=${this.hass.localize(
"ui.panel.lovelace.editor.card.weather-forecast.show_forecast"
"ui.panel.lovelace.editor.card.weather-forecast.show_both"
)}
.dir=${computeRTLDirection(this.hass)}
>
<ha-switch
.checked=${this._config!.show_forecast !== false}
<ha-radio
.disabled=${this._has_forecast === false}
.checked=${this._has_forecast === true &&
this._show_current &&
this._show_forecast}
.configValue=${"show_both"}
@change=${this._valueChanged}
></ha-radio
></ha-formfield>
<ha-formfield
.label=${this.hass.localize(
"ui.panel.lovelace.editor.card.weather-forecast.show_only_current"
)}
.dir=${computeRTLDirection(this.hass)}
>
<ha-radio
.disabled=${this._has_forecast === false}
.checked=${this._has_forecast === false ||
(this._show_current && !this._show_forecast)}
.configValue=${"show_current"}
@change=${this._valueChanged}
></ha-radio
></ha-formfield>
<ha-formfield
.label=${this.hass.localize(
"ui.panel.lovelace.editor.card.weather-forecast.show_only_forecast"
)}
.dir=${computeRTLDirection(this.hass)}
>
<ha-radio
.disabled=${this._has_forecast === false}
.checked=${this._has_forecast === true &&
!this._show_current &&
this._show_forecast}
.configValue=${"show_forecast"}
@change=${this._valueChanged}
></ha-switch
></ha-radio
></ha-formfield>
</div>
</div>
@ -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 {

View File

@ -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": {