Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 37 additions & 5 deletions src/panels/lovelace/cards/hui-entity-filter-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,38 @@ import { createCardElement } from "../common/create-card-element";
import { processConfigEntities } from "../common/process-config-entities";
import { LovelaceCard } from "../types";
import { LovelaceCardConfig } from "../../../data/lovelace";
import { EntityConfig } from "../entity-rows/types";
import { EntityFilterEntityConfig } from "../entity-rows/types";
import { HomeAssistant } from "../../../types";
import { EntityFilterCardConfig } from "./types";
import { evaluateFilter } from "../common/evaluate-filter";

class EntityFilterCard extends HTMLElement implements LovelaceCard {
public isPanel?: boolean;
private _element?: LovelaceCard;
private _config?: EntityFilterCardConfig;
private _configEntities?: EntityConfig[];
private _configEntities?: EntityFilterEntityConfig[];
private _baseCardConfig?: LovelaceCardConfig;
private _hass?: HomeAssistant;
private _oldEntities?: EntityConfig[];
private _oldEntities?: EntityFilterEntityConfig[];

public getCardSize(): number {
return this._element ? this._element.getCardSize() : 1;
}

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.");
}

Expand Down Expand Up @@ -56,7 +69,26 @@ class EntityFilterCard extends HTMLElement implements LovelaceCard {

const entitiesList = this._configEntities.filter((entityConf) => {
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) {
Expand Down
6 changes: 3 additions & 3 deletions src/panels/lovelace/cards/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LovelaceCardConfig, ActionConfig } from "../../../data/lovelace";
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 { HuiImage } from "../components/hui-image";

Expand Down Expand Up @@ -50,8 +50,8 @@ export interface EntityButtonCardConfig extends LovelaceCardConfig {

export interface EntityFilterCardConfig extends LovelaceCardConfig {
type: "entity-filter";
entities: Array<EntityConfig | string>;
state_filter: string[];
entities: Array<EntityFilterEntityConfig | string>;
state_filter: Array<{ key: string } | string>;
card: Partial<LovelaceCardConfig>;
show_empty?: boolean;
}
Expand Down
29 changes: 29 additions & 0 deletions src/panels/lovelace/common/evaluate-filter.ts
Original file line number Diff line number Diff line change
@@ -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;
}
};
3 changes: 3 additions & 0 deletions src/panels/lovelace/entity-rows/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export interface EntityConfig {
icon?: string;
image?: string;
}
export interface EntityFilterEntityConfig extends EntityConfig {
state_filter?: Array<{ key: string } | string>;
}
export interface DividerConfig {
type: "divider";
style: string;
Expand Down