mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 09:16:38 +00:00
Expand entity-filter options (#3692)
* Expand entity-filter options Closes https://github.com/home-assistant/home-assistant-polymer/issues/3543 Adds the following to `state_filter`: - `operator` option. Specify operator to use in comparison. - `value` option. Specify value to compare against. - `attribute` option. Specify attribute to use instead of state in comparison. e.g. ```yaml type: entity-filter state_filter: - "on" - operator: ">" value: 90 entities: - sensor.water_leak - sensor.outside_temp - entity: sensor.humidity_and_temp state_filter: operator: ">" value: 50 attribute: humidity ``` * Update evaluate-filter.ts * verify state_filter exists on card or each entity * address review comments * apply Bram's suggestion * address review comments * cleanup
This commit is contained in:
parent
38b817bd67
commit
886c6dd88c
@ -2,25 +2,38 @@ import { createCardElement } from "../common/create-card-element";
|
|||||||
import { processConfigEntities } from "../common/process-config-entities";
|
import { processConfigEntities } from "../common/process-config-entities";
|
||||||
import { LovelaceCard } from "../types";
|
import { LovelaceCard } from "../types";
|
||||||
import { LovelaceCardConfig } from "../../../data/lovelace";
|
import { LovelaceCardConfig } from "../../../data/lovelace";
|
||||||
import { EntityConfig } from "../entity-rows/types";
|
import { EntityFilterEntityConfig } from "../entity-rows/types";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { EntityFilterCardConfig } from "./types";
|
import { EntityFilterCardConfig } from "./types";
|
||||||
|
import { evaluateFilter } from "../common/evaluate-filter";
|
||||||
|
|
||||||
class EntityFilterCard extends HTMLElement implements LovelaceCard {
|
class EntityFilterCard extends HTMLElement implements LovelaceCard {
|
||||||
public isPanel?: boolean;
|
public isPanel?: boolean;
|
||||||
private _element?: LovelaceCard;
|
private _element?: LovelaceCard;
|
||||||
private _config?: EntityFilterCardConfig;
|
private _config?: EntityFilterCardConfig;
|
||||||
private _configEntities?: EntityConfig[];
|
private _configEntities?: EntityFilterEntityConfig[];
|
||||||
private _baseCardConfig?: LovelaceCardConfig;
|
private _baseCardConfig?: LovelaceCardConfig;
|
||||||
private _hass?: HomeAssistant;
|
private _hass?: HomeAssistant;
|
||||||
private _oldEntities?: EntityConfig[];
|
private _oldEntities?: EntityFilterEntityConfig[];
|
||||||
|
|
||||||
public getCardSize(): number {
|
public getCardSize(): number {
|
||||||
return this._element ? this._element.getCardSize() : 1;
|
return this._element ? this._element.getCardSize() : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setConfig(config: EntityFilterCardConfig): void {
|
public setConfig(config: EntityFilterCardConfig): void {
|
||||||
if (!config.state_filter || !Array.isArray(config.state_filter)) {
|
if (!config.entities || !Array.isArray(config.entities)) {
|
||||||
|
throw new Error("entities must be specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(config.state_filter && Array.isArray(config.state_filter)) &&
|
||||||
|
!config.entities.every(
|
||||||
|
(entity) =>
|
||||||
|
typeof entity === "object" &&
|
||||||
|
entity.state_filter &&
|
||||||
|
Array.isArray(entity.state_filter)
|
||||||
|
)
|
||||||
|
) {
|
||||||
throw new Error("Incorrect filter config.");
|
throw new Error("Incorrect filter config.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +69,26 @@ class EntityFilterCard extends HTMLElement implements LovelaceCard {
|
|||||||
|
|
||||||
const entitiesList = this._configEntities.filter((entityConf) => {
|
const entitiesList = this._configEntities.filter((entityConf) => {
|
||||||
const stateObj = hass.states[entityConf.entity];
|
const stateObj = hass.states[entityConf.entity];
|
||||||
return stateObj && this._config!.state_filter.includes(stateObj.state);
|
|
||||||
|
if (!stateObj) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entityConf.state_filter) {
|
||||||
|
for (const filter of entityConf.state_filter) {
|
||||||
|
if (evaluateFilter(stateObj, filter)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const filter of this._config!.state_filter) {
|
||||||
|
if (evaluateFilter(stateObj, filter)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (entitiesList.length === 0 && this._config.show_empty === false) {
|
if (entitiesList.length === 0 && this._config.show_empty === false) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { LovelaceCardConfig, ActionConfig } from "../../../data/lovelace";
|
import { LovelaceCardConfig, ActionConfig } from "../../../data/lovelace";
|
||||||
import { Condition } from "../common/validate-condition";
|
import { Condition } from "../common/validate-condition";
|
||||||
import { EntityConfig } from "../entity-rows/types";
|
import { EntityConfig, EntityFilterEntityConfig } from "../entity-rows/types";
|
||||||
import { LovelaceElementConfig } from "../elements/types";
|
import { LovelaceElementConfig } from "../elements/types";
|
||||||
import { HuiImage } from "../components/hui-image";
|
import { HuiImage } from "../components/hui-image";
|
||||||
|
|
||||||
@ -50,8 +50,8 @@ export interface EntityButtonCardConfig extends LovelaceCardConfig {
|
|||||||
|
|
||||||
export interface EntityFilterCardConfig extends LovelaceCardConfig {
|
export interface EntityFilterCardConfig extends LovelaceCardConfig {
|
||||||
type: "entity-filter";
|
type: "entity-filter";
|
||||||
entities: Array<EntityConfig | string>;
|
entities: Array<EntityFilterEntityConfig | string>;
|
||||||
state_filter: string[];
|
state_filter: Array<{ key: string } | string>;
|
||||||
card: Partial<LovelaceCardConfig>;
|
card: Partial<LovelaceCardConfig>;
|
||||||
show_empty?: boolean;
|
show_empty?: boolean;
|
||||||
}
|
}
|
||||||
|
29
src/panels/lovelace/common/evaluate-filter.ts
Normal file
29
src/panels/lovelace/common/evaluate-filter.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
|
export const evaluateFilter = (stateObj: HassEntity, filter: any): boolean => {
|
||||||
|
const operator = filter.operator || "==";
|
||||||
|
const value = filter.value || filter;
|
||||||
|
const state = filter.attribute
|
||||||
|
? stateObj.attributes[filter.attribute]
|
||||||
|
: stateObj.state;
|
||||||
|
|
||||||
|
switch (operator) {
|
||||||
|
case "==":
|
||||||
|
return state === value;
|
||||||
|
case "<=":
|
||||||
|
return state <= value;
|
||||||
|
case "<":
|
||||||
|
return state < value;
|
||||||
|
case ">=":
|
||||||
|
return state >= value;
|
||||||
|
case ">":
|
||||||
|
return state > value;
|
||||||
|
case "!=":
|
||||||
|
return state !== value;
|
||||||
|
case "regex": {
|
||||||
|
return state.match(value);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
@ -7,6 +7,9 @@ export interface EntityConfig {
|
|||||||
icon?: string;
|
icon?: string;
|
||||||
image?: string;
|
image?: string;
|
||||||
}
|
}
|
||||||
|
export interface EntityFilterEntityConfig extends EntityConfig {
|
||||||
|
state_filter?: Array<{ key: string } | string>;
|
||||||
|
}
|
||||||
export interface DividerConfig {
|
export interface DividerConfig {
|
||||||
type: "divider";
|
type: "divider";
|
||||||
style: string;
|
style: string;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user