Skip to content

Commit

Permalink
entity-filter: add ability to filter through entity_id value
Browse files Browse the repository at this point in the history
  • Loading branch information
Quentame committed Dec 29, 2023
1 parent 5e27940 commit dfdd023
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 37 deletions.
66 changes: 64 additions & 2 deletions gallery/src/pages/lovelace/entity-filter-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,36 @@ const ENTITIES = [
getEntity("light", "ceiling_lights", "off", {
friendly_name: "Ceiling Lights",
}),
getEntity("sensor", "gas_station_auchan_saint_priest_e10", 1.712, {
device_class: "monetary",
icon: "mdi:gas-station",
friendly_name: "Gas station Auchan Saint Priest E10",
unit_of_measurement: "€",
}),
getEntity("sensor", "gas_station_carrefour_venissieux_e10", 1.724, {
device_class: "monetary",
icon: "mdi:gas-station",
friendly_name: "Gas station Carrefour Venissieux E10",
unit_of_measurement: "€",
}),
getEntity("sensor", "gas_station_relais_lyon_mermoz_e10", 1.751, {
device_class: "monetary",
icon: "mdi:gas-station",
friendly_name: "Gas station Relais Lyon Mermoz E10",
unit_of_measurement: "€",
}),
getEntity("sensor", "gas_station_lowest_price", 1.712, {
state_class: "measurement",
min_entity_id: "sensor.gas_station_auchan_saint_priest_e10",
icon: "mdi:gas-station-in-use",
friendly_name: "Gas station Lowest Price",
unit_of_measurement: "€",
}),
];

const CONFIGS = [
{
heading: "Unfiltered controller",
heading: "Unfiltered entities",
config: `
- type: entities
entities:
Expand All @@ -52,7 +77,7 @@ const CONFIGS = [
`,
},
{
heading: "Filtered entities card",
heading: "Filtered entities",
config: `
- type: entity-filter
entities:
Expand Down Expand Up @@ -107,6 +132,43 @@ const CONFIGS = [
title: Custom Title
`,
},
{
heading: "Unfiltered number entities",
config: `
- type: entities
entities:
- sensor.gas_station_auchan_saint_priest_e10
- sensor.gas_station_carrefour_venissieux_e10
- sensor.gas_station_relais_lyon_mermoz_e10
- sensor.gas_station_lowest_price
`,
},
{
heading: "Filtered entities with operator & number value",
config: `
- type: entity-filter
entities:
- sensor.gas_station_auchan_saint_priest_e10
- sensor.gas_station_carrefour_venissieux_e10
- sensor.gas_station_relais_lyon_mermoz_e10
state_filter:
- operator: <=
value: 1.73
`,
},
{
heading: "Filtered entities with operator & entity_id value",
config: `
- type: entity-filter
entities:
- sensor.gas_station_auchan_saint_priest_e10
- sensor.gas_station_carrefour_venissieux_e10
- sensor.gas_station_relais_lyon_mermoz_e10
state_filter:
- operator: ==
value: sensor.gas_station_lowest_price
`,
},
];

@customElement("demo-lovelace-entity-filter-card")
Expand Down
22 changes: 5 additions & 17 deletions src/panels/lovelace/badges/hui-entity-filter-badge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,11 @@ class EntityFilterBadge extends ReactiveElement implements LovelaceBadge {
}

const entitiesList = this._configEntities.filter((entityConf) => {
const stateObj = this.hass.states[entityConf.entity];

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;
}
const state_filters =
entityConf.state_filter ?? this._config!.state_filter;
for (const filter of state_filters) {
if (evaluateFilter(this.hass, entityConf.entity, filter)) {
return true;
}
}

Expand Down
22 changes: 5 additions & 17 deletions src/panels/lovelace/cards/hui-entity-filter-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,23 +122,11 @@ class EntityFilterCard extends ReactiveElement implements LovelaceCard {
}

const entitiesList = this._configEntities.filter((entityConf) => {
const stateObj = this.hass!.states[entityConf.entity];

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;
}
const state_filters =
entityConf.state_filter ?? this._config!.state_filter;
for (const filter of state_filters) {
if (evaluateFilter(this.hass!, entityConf.entity, filter)) {
return true;
}
}

Expand Down
21 changes: 20 additions & 1 deletion src/panels/lovelace/common/evaluate-filter.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
import { HassEntity } from "home-assistant-js-websocket";
import { HomeAssistant } from "../../../types";

export const evaluateFilter = (
hass: HomeAssistant,
current_entity_id: string,
filter: any
): boolean => {
const stateObj: HassEntity = hass.states[current_entity_id];

if (!stateObj) {
return false;
}

export const evaluateFilter = (stateObj: HassEntity, filter: any): boolean => {
const operator = filter.operator || "==";
let value = filter.value ?? filter;
let state = filter.attribute
? stateObj.attributes[filter.attribute]
: stateObj.state;

if (typeof value === "string" && value.includes(".")) {
value = hass.states[value]?.state;

if (!value) {
return false;
}
}

if (operator === "==" || operator === "!=") {
const valueIsNumeric =
typeof value === "number" ||
Expand Down

0 comments on commit dfdd023

Please sign in to comment.