122 lines
4.6 KiB
JavaScript
122 lines
4.6 KiB
JavaScript
import { areaByName, areaDevices, deviceByName, deviceEntities } from "card-tools/src/devices";
|
|
|
|
function match(pattern, value) {
|
|
if(typeof(value) === "string" && typeof(pattern) === "string") {
|
|
if((pattern.startsWith('/') && pattern.endsWith('/')) || pattern.indexOf('*') !== -1) {
|
|
if(!pattern.startsWith('/')) { // Convert globs to regex
|
|
pattern = pattern
|
|
.replace(/\./g, '\.')
|
|
.replace(/\*/g, '.*');
|
|
pattern = `/^${pattern}$/`;
|
|
}
|
|
let regex = new RegExp(pattern.slice(1,-1));
|
|
return regex.test(value);
|
|
}
|
|
}
|
|
|
|
if(typeof(pattern) === "string") {
|
|
// Comparisons assume numerical values
|
|
if(pattern.startsWith("<=")) return parseFloat(value) <= parseFloat(pattern.substr(2));
|
|
if(pattern.startsWith(">=")) return parseFloat(value) >= parseFloat(pattern.substr(2));
|
|
if(pattern.startsWith("<")) return parseFloat(value) < parseFloat(pattern.substr(1));
|
|
if(pattern.startsWith(">")) return parseFloat(value) > parseFloat(pattern.substr(1));
|
|
if(pattern.startsWith("!")) return parseFloat(value) != parseFloat(pattern.substr(1));
|
|
if(pattern.startsWith("=")) return parseFloat(value) == parseFloat(pattern.substr(1));
|
|
}
|
|
|
|
return pattern === value;
|
|
}
|
|
|
|
export function entity_filter(hass, filter) {
|
|
return function(e) {
|
|
const entity = typeof(e) === "string"
|
|
? hass.states[e]
|
|
: hass.states[e.entity];
|
|
if(!e) return false;
|
|
for (const [key, value] of Object.entries(filter)) {
|
|
switch(key.split(" ")[0]) {
|
|
case "options":
|
|
case "sort":
|
|
break;
|
|
|
|
case "domain":
|
|
if(!match(value, entity.entity_id.split('.')[0]))
|
|
return false;
|
|
break;
|
|
|
|
case "entity_id":
|
|
if(!match(value, entity.entity_id))
|
|
return false;
|
|
break;
|
|
|
|
case "state":
|
|
if(!match(value, entity.state))
|
|
return false;
|
|
break;
|
|
|
|
case "name":
|
|
if(!entity.attributes.friendly_name
|
|
|| !match(value, entity.attributes.friendly_name))
|
|
return false;
|
|
break;
|
|
|
|
case "group":
|
|
if(!value.startsWith("group.")
|
|
|| !hass.states[value]
|
|
|| !hass.states[value].attributes.entity_id
|
|
|| !hass.states[value].attributes.entity_id.includes(entity.entity_id)
|
|
)
|
|
return false;
|
|
break;
|
|
|
|
case "attributes":
|
|
for(const [k, v] of Object.entries(value)) {
|
|
let attr = k.split(" ")[0];
|
|
let entityAttribute = entity.attributes;
|
|
while(attr && entityAttribute) {
|
|
let step;
|
|
[step, attr] = attr.split(":");
|
|
entityAttribute = entityAttribute[step];
|
|
}
|
|
if(entityAttribute === undefined
|
|
|| (v && !match(v, entityAttribute))
|
|
)
|
|
return false;
|
|
continue;
|
|
}
|
|
break;
|
|
|
|
case "not":
|
|
if(entity_filter(hass,value)(e))
|
|
return false;
|
|
break;
|
|
|
|
case "device":
|
|
let _deviceMatch = false;
|
|
for(const d of window.cardToolsData.devices) {
|
|
if (match(value, d.name)){
|
|
if(deviceEntities(d).includes(entity.entity_id))
|
|
_deviceMatch = true;
|
|
}
|
|
}
|
|
if(!_deviceMatch) return false;
|
|
break;
|
|
|
|
case "area":
|
|
let _areaMatch = false;
|
|
for (const a of window.cardToolsData.areas) {
|
|
if(match(value, a.name)) {
|
|
if(areaDevices(a).flatMap(deviceEntities).includes(entity.entity_id))
|
|
_areaMatch = true;
|
|
}
|
|
}
|
|
if(!_areaMatch) return false;
|
|
break;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
} |