Skip to content

Commit

Permalink
Add entity filter
Browse files Browse the repository at this point in the history
  • Loading branch information
balloob committed Oct 12, 2018
1 parent ee53ee4 commit a0611c2
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/common/entity/entity_filter.js
@@ -0,0 +1,62 @@
import computeDomain from "./compute_domain.js";

export function generateFilter(
includeDomains = [],
includeEntities = [],
excludeDomains = [],
excludeEntities = []
) {
includeDomains = new Set(includeDomains);
includeEntities = new Set(includeEntities);
excludeDomains = new Set(excludeDomains);
excludeEntities = new Set(excludeEntities);

const haveInclude = includeDomains.size | (includeEntities.size !== 0);
const haveExclude = excludeDomains.size | (excludeEntities.size !== 0);

// Case 1 - no includes or excludes - pass all entities
if (!haveInclude && !haveExclude) {
return () => true;
}

// Case 2 - includes, no excludes - only include specified entities
if (haveInclude && !haveExclude) {
return (entityId) =>
includeEntities.has(entityId) ||
includeDomains.has(computeDomain(entityId));
}

// Case 3 - excludes, no includes - only exclude specified entities
if (!haveInclude && haveExclude) {
return (entityId) =>
!excludeEntities.has(entityId) &&
!excludeDomains.has(computeDomain(entityId));
}

// Case 4 - both includes and excludes specified
// Case 4a - include domain specified
// - if domain is included, and entity not excluded, pass
// - if domain is not included, and entity not included, fail
// note: if both include and exclude domains specified,
// the exclude domains are ignored
if (includeDomains.size) {
return (entityId) =>
includeDomains.has(computeDomain(entityId))
? !excludeEntities.has(entityId)
: includeEntities.has(entityId);
}

// Case 4b - exclude domain specified
// - if domain is excluded, and entity not included, fail
// - if domain is not excluded, and entity not excluded, pass
if (excludeDomains.size) {
return (entityId) =>
excludeDomains.has(computeDomain(entityId))
? includeEntities.has(entityId)
: !excludeEntities.has(entityId);
}

// Case 4c - neither include or exclude domain specified
// - Only pass if entity is included. Ignore entity excludes.
return (entityId) => includeEntities.has(entityId);
}
88 changes: 88 additions & 0 deletions test-mocha/common/util/entity_filter.js
@@ -0,0 +1,88 @@
import { generateFilter } from "../../../src/common/entity/entity_filter.js";

const assert = require("assert");

describe("EntityFilter", () => {
// case 1
it("passes all when no filters passed in", () => {
const filter = generateFilter();

assert(filter("sensor.test"));
assert(filter("sun.sun"));
assert(filter("light.test"));
});

// case 2
it("allows whitelisting entities by entity id", () => {
const filter = generateFilter(null, ["light.kitchen"]);

assert(filter("light.kitchen"));
assert(!filter("light.living_room"));
});

it("allows whitelisting entities by domain", () => {
const filter = generateFilter(["switch"]);

assert(filter("switch.bla"));
assert(!filter("light.kitchen"));
});

// case 3
it("allows blacklisting entities by entity id", () => {
const filter = generateFilter(null, null, null, ["light.kitchen"]);

assert(!filter("light.kitchen"));
assert(filter("light.living_room"));
});

it("allows blacklisting entities by domain", () => {
const filter = generateFilter(null, null, ["switch"]);

assert(!filter("switch.bla"));
assert(filter("light.kitchen"));
});

// case 4a
it("allows whitelisting domain and blacklisting entity", () => {
const filter = generateFilter(["switch"], null, null, ["switch.kitchen"]);

assert(filter("switch.living_room"));
assert(!filter("switch.kitchen"));
assert(!filter("sensor.bla"));
});

it("allows whitelisting entity while whitelisting other domains", () => {
const filter = generateFilter(["switch"], ["light.kitchen"]);

assert(filter("switch.living_room"));
assert(filter("light.kitchen"));
assert(!filter("sensor.bla"));
});

// case 4b
it("allows blacklisting domain and whitelisting entity", () => {
const filter = generateFilter(null, ["switch.kitchen"], ["switch"]);

assert(filter("switch.kitchen"));
assert(!filter("switch.living_room"));
assert(filter("sensor.bla"));
});

it("allows blacklisting domain and excluding entities", () => {
const filter = generateFilter(null, null, ["switch"], ["light.kitchen"]);

assert(!filter("switch.living_room"));
assert(!filter("light.kitchen"));
assert(filter("sensor.bla"));
});

// case 4c
it("allows whitelisting entities", () => {
const filter = generateFilter(null, ["light.kitchen"]);

assert(filter("light.kitchen"));
assert(!filter("switch.living_room"));
assert(!filter("light.living_room"));
assert(!filter("sensor.bla"));
});
});

0 comments on commit a0611c2

Please sign in to comment.