diff --git a/src/components/entity/state-badge.ts b/src/components/entity/state-badge.ts
index d000865d5d..b01ea63f34 100644
--- a/src/components/entity/state-badge.ts
+++ b/src/components/entity/state-badge.ts
@@ -20,7 +20,7 @@ import { computeActiveState } from "../../common/entity/compute_active_state";
import { ifDefined } from "lit-html/directives/if-defined";
import { iconColorCSS } from "../../common/style/icon_color_css";
-class StateBadge extends LitElement {
+export class StateBadge extends LitElement {
public hass?: HomeAssistant;
@property() public stateObj?: HassEntity;
@property() public overrideIcon?: string;
diff --git a/src/panels/lovelace/cards/hui-entities-card.ts b/src/panels/lovelace/cards/hui-entities-card.ts
index b892899ba8..c43a70442e 100644
--- a/src/panels/lovelace/cards/hui-entities-card.ts
+++ b/src/panels/lovelace/cards/hui-entities-card.ts
@@ -14,7 +14,11 @@ import "../components/hui-entities-toggle";
import { HomeAssistant } from "../../../types";
import { LovelaceRow } from "../entity-rows/types";
-import { LovelaceCard, LovelaceCardEditor } from "../types";
+import {
+ LovelaceCard,
+ LovelaceCardEditor,
+ LovelaceHeaderFooter,
+} from "../types";
import { processConfigEntities } from "../common/process-config-entities";
import { createRowElement } from "../create-element/create-row-element";
import { EntitiesCardConfig, EntitiesCardEntityConfig } from "./types";
@@ -48,6 +52,11 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
(element as LovelaceRow).hass = hass;
}
);
+ this.shadowRoot!.querySelectorAll(".header-footer > *").forEach(
+ (element: unknown) => {
+ (element as LovelaceHeaderFooter).hass = hass;
+ }
+ );
const entitiesToggle = this.shadowRoot!.querySelector(
"hui-entities-toggle"
);
@@ -135,6 +144,7 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
this.renderEntity(entityConf)
)}
+
${this._config.footer
? this.renderHeaderFooter(this._config.footer, "footer")
: ""}
@@ -192,7 +202,7 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
element.hass = this._hass;
}
return html`
-
${element}
+
`;
}
diff --git a/src/panels/lovelace/common/compute-tooltip.ts b/src/panels/lovelace/common/compute-tooltip.ts
index 0b972a7e8e..b5d7ed9955 100644
--- a/src/panels/lovelace/common/compute-tooltip.ts
+++ b/src/panels/lovelace/common/compute-tooltip.ts
@@ -1,9 +1,8 @@
import { computeStateName } from "../../../common/entity/compute_state_name";
import { HomeAssistant } from "../../../types";
-import { LovelaceElementConfig } from "../elements/types";
import { ActionConfig } from "../../../data/lovelace";
-interface Config extends LovelaceElementConfig {
+interface Config {
entity?: string;
title?: string;
tap_action?: ActionConfig;
@@ -30,6 +29,10 @@ export const computeTooltip = (hass: HomeAssistant, config: Config): string => {
: config.entity;
}
+ if (!config.tap_action && !config.hold_action) {
+ return stateName;
+ }
+
const tapTooltip = config.tap_action
? computeActionTooltip(hass, stateName, config.tap_action, false)
: "";
diff --git a/src/panels/lovelace/create-element/create-header-footer-element.ts b/src/panels/lovelace/create-element/create-header-footer-element.ts
index 76ad7f3b2c..28d74d148b 100644
--- a/src/panels/lovelace/create-element/create-header-footer-element.ts
+++ b/src/panels/lovelace/create-element/create-header-footer-element.ts
@@ -1,8 +1,9 @@
import "../header-footer/hui-picture-header-footer";
+import "../header-footer/hui-buttons-header-footer";
import { LovelaceHeaderFooterConfig } from "../header-footer/types";
import { createLovelaceElement } from "./create-element-base";
-const SPECIAL_TYPES = new Set(["picture"]);
+const SPECIAL_TYPES = new Set(["picture", "buttons"]);
export const createHeaderFooterElement = (config: LovelaceHeaderFooterConfig) =>
createLovelaceElement("header-footer", config, SPECIAL_TYPES);
diff --git a/src/panels/lovelace/editor/config-elements/hui-entities-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-entities-card-editor.ts
index 4f34d5ff98..3f5953d7e8 100644
--- a/src/panels/lovelace/editor/config-elements/hui-entities-card-editor.ts
+++ b/src/panels/lovelace/editor/config-elements/hui-entities-card-editor.ts
@@ -31,7 +31,7 @@ import {
EntitiesCardConfig,
EntitiesCardEntityConfig,
} from "../../cards/types";
-import { pictureHeaderFooterConfigStruct } from "../../header-footer/types";
+import { headerFooterConfigStructs } from "../../header-footer/types";
const cardConfigStruct = struct({
type: "string",
@@ -39,8 +39,8 @@ const cardConfigStruct = struct({
theme: "string?",
show_header_toggle: "boolean?",
entities: [entitiesConfigStruct],
- header: struct.optional(pictureHeaderFooterConfigStruct),
- footer: struct.optional(pictureHeaderFooterConfigStruct),
+ header: struct.optional(headerFooterConfigStructs),
+ footer: struct.optional(headerFooterConfigStructs),
});
@customElement("hui-entities-card-editor")
diff --git a/src/panels/lovelace/header-footer/hui-buttons-header-footer.ts b/src/panels/lovelace/header-footer/hui-buttons-header-footer.ts
new file mode 100644
index 0000000000..35e3b6eefd
--- /dev/null
+++ b/src/panels/lovelace/header-footer/hui-buttons-header-footer.ts
@@ -0,0 +1,102 @@
+import {
+ html,
+ LitElement,
+ TemplateResult,
+ customElement,
+ css,
+ CSSResult,
+ queryAll,
+} from "lit-element";
+import "@material/mwc-ripple";
+
+import "../../../components/entity/state-badge";
+import "../../../components/ha-card";
+import "../../../components/ha-icon";
+import "../components/hui-warning-element";
+
+import { HomeAssistant } from "../../../types";
+import { LovelaceHeaderFooter } from "../types";
+import { ButtonsHeaderFooterConfig } from "./types";
+import { EntityConfig } from "../entity-rows/types";
+import { processConfigEntities } from "../common/process-config-entities";
+import { toggleEntity } from "../common/entity/toggle-entity";
+import { computeTooltip } from "../common/compute-tooltip";
+// tslint:disable-next-line: no-duplicate-imports
+import { StateBadge } from "../../../components/entity/state-badge";
+
+@customElement("hui-buttons-header-footer")
+export class HuiButtonsHeaderFooter extends LitElement
+ implements LovelaceHeaderFooter {
+ public static getStubConfig(): object {
+ return { entities: [] };
+ }
+
+ private _configEntities?: EntityConfig[];
+ private _hass?: HomeAssistant;
+ @queryAll("state-badge") private _badges!: StateBadge[];
+
+ public setConfig(config: ButtonsHeaderFooterConfig): void {
+ this._configEntities = processConfigEntities(config.entities);
+ this.requestUpdate();
+ }
+
+ set hass(hass: HomeAssistant) {
+ this._hass = hass;
+ this._badges.forEach((badge, index: number) => {
+ badge.hass = hass;
+ badge.stateObj = hass.states[this._configEntities![index].entity];
+ });
+ }
+
+ protected render(): TemplateResult | void {
+ return html`
+ ${(this._configEntities || []).map((entityConf) => {
+ const stateObj = this._hass!.states[entityConf.entity];
+ if (!stateObj) {
+ return html`
`;
+ }
+
+ return html`
+
+
+
+
+ `;
+ })}
+ `;
+ }
+
+ private async _toggle(ev) {
+ await toggleEntity(this._hass!, ev.target.stateObj.entity_id);
+ }
+
+ static get styles(): CSSResult {
+ return css`
+ :host {
+ display: flex;
+ justify-content: space-evenly;
+ }
+ .missing {
+ color: #fce588;
+ }
+ state-badge {
+ cursor: pointer;
+ }
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "hui-buttons-header-footer": HuiButtonsHeaderFooter;
+ }
+}
diff --git a/src/panels/lovelace/header-footer/types.ts b/src/panels/lovelace/header-footer/types.ts
index 03a3a18f36..65c4ba6c7f 100644
--- a/src/panels/lovelace/header-footer/types.ts
+++ b/src/panels/lovelace/header-footer/types.ts
@@ -1,11 +1,15 @@
import { ActionConfig } from "../../../data/lovelace";
import { struct } from "../common/structs/struct";
-import { actionConfigStruct } from "../editor/types";
+import { actionConfigStruct, entitiesConfigStruct } from "../editor/types";
export interface LovelaceHeaderFooterConfig {
type: string;
}
+export interface ButtonsHeaderFooterConfig extends LovelaceHeaderFooterConfig {
+ entities: string[];
+}
+
export interface PictureHeaderFooterConfig extends LovelaceHeaderFooterConfig {
image: string;
tap_action?: ActionConfig;
@@ -20,3 +24,13 @@ export const pictureHeaderFooterConfigStruct = struct({
hold_action: struct.optional(actionConfigStruct),
double_tap_action: struct.optional(actionConfigStruct),
});
+
+export const buttonsHeaderFooterConfigStruct = struct({
+ type: "string",
+ entities: [entitiesConfigStruct],
+});
+
+export const headerFooterConfigStructs = struct.union([
+ pictureHeaderFooterConfigStruct,
+ buttonsHeaderFooterConfigStruct,
+]);