Less clever, more stable. Really fix #37
This commit is contained in:
parent
52b2a77bfa
commit
bc73013f6d
File diff suppressed because one or more lines are too long
210
src/filter.js
210
src/filter.js
@ -1,122 +1,126 @@
|
|||||||
import { areaByName, areaDevices, deviceByName, deviceEntities } from "card-tools/src/devices";
|
import { areaByName, areaDevices, deviceByName, deviceEntities } from "card-tools/src/devices";
|
||||||
|
|
||||||
function match(pattern, value) {
|
function match(pattern, value) {
|
||||||
if(typeof(value) === "string" && typeof(pattern) === "string") {
|
if(typeof(value) === "string" && typeof(pattern) === "string") {
|
||||||
if((pattern.startsWith('/') && pattern.endsWith('/')) || pattern.indexOf('*') !== -1) {
|
if((pattern.startsWith('/') && pattern.endsWith('/')) || pattern.indexOf('*') !== -1) {
|
||||||
if(!pattern.startsWith('/')) { // Convert globs to regex
|
if(!pattern.startsWith('/')) { // Convert globs to regex
|
||||||
pattern = pattern
|
pattern = pattern
|
||||||
.replace(/\./g, '\.')
|
.replace(/\./g, '\.')
|
||||||
.replace(/\*/g, '.*');
|
.replace(/\*/g, '.*');
|
||||||
pattern = `/^${pattern}$/`;
|
pattern = `/^${pattern}$/`;
|
||||||
}
|
}
|
||||||
let regex = new RegExp(pattern.slice(1,-1));
|
let regex = new RegExp(pattern.slice(1,-1));
|
||||||
return regex.test(value);
|
return regex.test(value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(typeof(pattern) === "string") {
|
if(typeof(pattern) === "string") {
|
||||||
// Comparisons assume numerical values
|
// 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(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));
|
||||||
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;
|
return pattern === value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function entity_filter(hass, filter) {
|
export function entity_filter(hass, filter) {
|
||||||
return function(e) {
|
return function(e) {
|
||||||
const entity = typeof(e) === "string"
|
const entity = typeof(e) === "string"
|
||||||
? hass.states[e]
|
? hass.states[e]
|
||||||
: hass.states[e.entity];
|
: hass.states[e.entity];
|
||||||
if(!e) return false;
|
if(!e) return false;
|
||||||
for (const [key, value] of Object.entries(filter)) {
|
for (const [key, value] of Object.entries(filter)) {
|
||||||
switch(key.split(" ")[0]) {
|
switch(key.split(" ")[0]) {
|
||||||
case "options":
|
case "options":
|
||||||
case "sort":
|
case "sort":
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "domain":
|
case "domain":
|
||||||
if(!match(value, entity.entity_id.split('.')[0]))
|
if(!match(value, entity.entity_id.split('.')[0]))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "entity_id":
|
case "entity_id":
|
||||||
if(!match(value, entity.entity_id))
|
if(!match(value, entity.entity_id))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "state":
|
case "state":
|
||||||
if(!match(value, entity.state))
|
if(!match(value, entity.state))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "name":
|
case "name":
|
||||||
if(!entity.attributes.friendly_name
|
if(!entity.attributes.friendly_name
|
||||||
|| !match(value, entity.attributes.friendly_name))
|
|| !match(value, entity.attributes.friendly_name))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "group":
|
case "group":
|
||||||
if(!value.startsWith("group.")
|
if(!value.startsWith("group.")
|
||||||
|| !hass.states[value]
|
|| !hass.states[value]
|
||||||
|| !hass.states[value].attributes.entity_id
|
|| !hass.states[value].attributes.entity_id
|
||||||
|| !hass.states[value].attributes.entity_id.includes(entity.entity_id)
|
|| !hass.states[value].attributes.entity_id.includes(entity.entity_id)
|
||||||
)
|
)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "attributes":
|
case "attributes":
|
||||||
for(const [k, v] of Object.entries(value)) {
|
for(const [k, v] of Object.entries(value)) {
|
||||||
let attr = k.split(" ")[0];
|
let attr = k.split(" ")[0];
|
||||||
let entityAttribute = entity.attributes;
|
let entityAttribute = entity.attributes;
|
||||||
while(attr && entityAttribute) {
|
while(attr && entityAttribute) {
|
||||||
let step;
|
let step;
|
||||||
[step, attr] = attr.split(":");
|
[step, attr] = attr.split(":");
|
||||||
entityAttribute = entityAttribute[step];
|
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;
|
|
||||||
}
|
}
|
||||||
|
if(entityAttribute === undefined
|
||||||
|
|| (v && !match(v, entityAttribute))
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "not":
|
||||||
|
if(entity_filter(hass,value)(e))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "device":
|
||||||
|
if(!window.cardToolsData || !window.cardToolsData.devices)
|
||||||
|
return false;
|
||||||
|
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":
|
||||||
|
if(!window.cardToolsData || !window.cardToolsData.areas)
|
||||||
|
return false;
|
||||||
|
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;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
303
src/main.js
303
src/main.js
@ -1,174 +1,171 @@
|
|||||||
import { LitElement, html, css } from "card-tools/src/lit-element";
|
import { LitElement, html, css } from "card-tools/src/lit-element";
|
||||||
import "card-tools/src/card-maker";
|
|
||||||
import { entity_filter } from "./filter";
|
import { entity_filter } from "./filter";
|
||||||
import { entity_sorter } from "./sort";
|
import { entity_sorter } from "./sort";
|
||||||
import { getData } from "card-tools/src/devices";
|
import { getData } from "card-tools/src/devices";
|
||||||
import { fireEvent } from "card-tools/src/event";
|
import { fireEvent } from "card-tools/src/event";
|
||||||
|
import { createCard } from "card-tools/src/lovelace-element";
|
||||||
|
import { hass } from "card-tools/src/hass";
|
||||||
|
|
||||||
class AutoEntities extends LitElement {
|
class AutoEntities extends LitElement {
|
||||||
|
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
hass: {},
|
hass: {},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
setConfig(config) {
|
||||||
|
if(!config || !config.card) {
|
||||||
|
throw new Error("Invalid configuration");
|
||||||
}
|
}
|
||||||
setConfig(config) {
|
if(!this._config) {
|
||||||
if(!config || !config.card) {
|
this._config = config;
|
||||||
throw new Error("Invalid configuration");
|
|
||||||
}
|
this.hass = hass();
|
||||||
if(!this._config) {
|
this._getEntities();
|
||||||
this._config = config;
|
this.cardConfig = {entities: this.entities, ...config.card};
|
||||||
this.cardConfig = {entities: [], ...config.card};
|
this.card = createCard(this.cardConfig);
|
||||||
this.entities = [];
|
} else {
|
||||||
} else {
|
this._config = config;
|
||||||
this._config = config;
|
this.hass = this.hass;
|
||||||
this.hass = this.hass;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _getEntities()
|
// Reevaluate all filters once areas have been loaded
|
||||||
|
getData().then(() => this._getEntities());
|
||||||
|
}
|
||||||
|
|
||||||
|
_getEntities()
|
||||||
|
{
|
||||||
|
let entities = [];
|
||||||
|
// Start with any entities added by the `entities` parameter
|
||||||
|
if(this._config.entities)
|
||||||
|
entities = entities.concat(this._config.entities)
|
||||||
|
.map((e) => {
|
||||||
|
if(typeof(e) === "string")
|
||||||
|
return {entity: e};
|
||||||
|
return e;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!this.hass || !this._config.filter) return entities;
|
||||||
|
|
||||||
|
if(this._config.filter.include) {
|
||||||
|
const all_entities = Object.keys(this.hass.states)
|
||||||
|
.map((e) => new Object({entity: e}));
|
||||||
|
|
||||||
|
for(const f of this._config.filter.include) {
|
||||||
|
if(f.type !== undefined) {
|
||||||
|
// If the filter has a type, it's a special entry
|
||||||
|
entities.push(f);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let add = all_entities.filter(entity_filter(this.hass, f))
|
||||||
|
.map((e) => new Object({...e, ...f.options}));
|
||||||
|
|
||||||
|
if(f.sort !== undefined) {
|
||||||
|
// Sort per filter
|
||||||
|
add = add.sort(entity_sorter(this.hass, f.sort));
|
||||||
|
}
|
||||||
|
entities = entities.concat(add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(this._config.filter.exclude) {
|
||||||
|
for(const f of this._config.filter.exclude) {
|
||||||
|
entities = entities.filter((e) => {
|
||||||
|
// Don't exclude special entries
|
||||||
|
if(typeof(e) !== "string" && e.entity === undefined) return true;
|
||||||
|
return !entity_filter(this.hass,f)(e)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._config.sort) {
|
||||||
|
// Sort everything
|
||||||
|
entities = entities.sort(entity_sorter(this.hass, this._config.sort));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._config.unique) {
|
||||||
|
function compare(a,b) {
|
||||||
|
if(typeof(a) !== typeof(b)) return false;
|
||||||
|
if(typeof(a) !== "object") return a===b;
|
||||||
|
if(Object.keys(a).some((k) => !Object.keys(b).includes(k))) return false;
|
||||||
|
|
||||||
|
return Object.keys(a).every((k) => compare(a[k], b[k]));
|
||||||
|
}
|
||||||
|
let newEntities = [];
|
||||||
|
for(const e of entities) {
|
||||||
|
if(newEntities.some((i) => compare(i,e))) continue;
|
||||||
|
newEntities.push(e);
|
||||||
|
}
|
||||||
|
entities = newEntities;
|
||||||
|
}
|
||||||
|
this.entities = entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
set entities(ent) {
|
||||||
|
function compare(a,b) {
|
||||||
|
if( a === b )
|
||||||
|
return true;
|
||||||
|
if( a == null || b == null)
|
||||||
|
return false;
|
||||||
|
if(a.length != b.length)
|
||||||
|
return false;
|
||||||
|
for(var i = 0; i < a.length; i++)
|
||||||
|
if(JSON.stringify(a[i]) !== JSON.stringify(b[i]))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(!compare(ent, this._entities))
|
||||||
{
|
{
|
||||||
let entities = [];
|
this._entities = ent;
|
||||||
// Start with any entities added by the `entities` parameter
|
this.cardConfig = {...this.cardConfig, entities: this._entities};
|
||||||
if(this._config.entities)
|
if(ent.length === 0 && this._config.show_empty === false) {
|
||||||
entities = entities.concat(this._config.entities)
|
this.style.display = "none";
|
||||||
.map((e) => {
|
this.style.margin = "0";
|
||||||
if(typeof(e) === "string")
|
} else {
|
||||||
return {entity: e};
|
this.style.display = null;
|
||||||
return e;
|
this.style.margin = null;
|
||||||
});
|
}
|
||||||
|
|
||||||
if(!this.hass || !this._config.filter) return entities;
|
|
||||||
|
|
||||||
if(this._config.filter.include) {
|
|
||||||
const all_entities = Object.keys(this.hass.states)
|
|
||||||
.map((e) => new Object({entity: e}));
|
|
||||||
|
|
||||||
for(const f of this._config.filter.include) {
|
|
||||||
if(f.type !== undefined) {
|
|
||||||
// If the filter has a type, it's a special entry
|
|
||||||
entities.push(f);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(f.device || f.area) {
|
|
||||||
await getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
let add = all_entities.filter(entity_filter(this.hass, f))
|
|
||||||
.map((e) => new Object({...e, ...f.options}));
|
|
||||||
|
|
||||||
if(f.sort !== undefined) {
|
|
||||||
// Sort per filter
|
|
||||||
add = add.sort(entity_sorter(this.hass, f.sort));
|
|
||||||
}
|
|
||||||
entities = entities.concat(add);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(this._config.filter.exclude) {
|
|
||||||
for(const f of this._config.filter.exclude) {
|
|
||||||
entities = entities.filter((e) => {
|
|
||||||
// Don't exclude special entries
|
|
||||||
if(typeof(e) !== "string" && e.entity === undefined) return true;
|
|
||||||
return !entity_filter(this.hass,f)(e)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this._config.sort) {
|
|
||||||
// Sort everything
|
|
||||||
entities = entities.sort(entity_sorter(this.hass, this._config.sort));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this._config.unique) {
|
|
||||||
function compare(a,b) {
|
|
||||||
if(typeof(a) !== typeof(b)) return false;
|
|
||||||
if(typeof(a) !== "object") return a===b;
|
|
||||||
if(Object.keys(a).some((k) => !Object.keys(b).includes(k))) return false;
|
|
||||||
|
|
||||||
return Object.keys(a).every((k) => compare(a[k], b[k]));
|
|
||||||
}
|
|
||||||
let newEntities = [];
|
|
||||||
for(const e of entities) {
|
|
||||||
if(newEntities.some((i) => compare(i,e))) continue;
|
|
||||||
newEntities.push(e);
|
|
||||||
}
|
|
||||||
entities = newEntities;
|
|
||||||
}
|
|
||||||
return entities;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
get entities() {
|
||||||
|
return this._entities;
|
||||||
|
}
|
||||||
|
|
||||||
set entities(ent) {
|
set cardConfig(cardConfig) {
|
||||||
function compare(a,b) {
|
this._cardConfig = cardConfig;
|
||||||
if( a === b )
|
if(this.card)
|
||||||
return true;
|
this.card.setConfig(cardConfig);
|
||||||
if( a == null || b == null)
|
}
|
||||||
return false;
|
get cardConfig() {
|
||||||
if(a.length != b.length)
|
return this._cardConfig;
|
||||||
return false;
|
}
|
||||||
for(var i = 0; i < a.length; i++)
|
|
||||||
if(JSON.stringify(a[i]) !== JSON.stringify(b[i]))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if(!compare(ent, this._entities))
|
|
||||||
{
|
|
||||||
this._entities = ent;
|
|
||||||
this.cardConfig = {...this.cardConfig, entities: this._entities};
|
|
||||||
if(ent.length === 0 && this._config.show_empty === false) {
|
|
||||||
this.style.display = "none";
|
|
||||||
this.style.margin = "0";
|
|
||||||
} else {
|
|
||||||
this.style.display = null;
|
|
||||||
this.style.margin = null;
|
|
||||||
}
|
|
||||||
this.requestUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
get entities() {
|
|
||||||
return this._entities;
|
|
||||||
}
|
|
||||||
|
|
||||||
set cardConfig(cardConfig) {
|
updated(changedProperties) {
|
||||||
this._cardConfig = cardConfig;
|
if(changedProperties.has("hass") && this.hass) {
|
||||||
if(this.querySelector("card-maker"))
|
this.card.hass = this.hass;
|
||||||
this.querySelector("card-maker").config = cardConfig;
|
// Run this in a timeout to improve performance
|
||||||
}
|
setTimeout(() => this._getEntities(), 0);
|
||||||
get cardConfig() {
|
|
||||||
return this._cardConfig;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
createRenderRoot() {
|
||||||
this.cardConfig = this._cardConfig;
|
return this;
|
||||||
}
|
}
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
${this.card}`;
|
||||||
|
}
|
||||||
|
|
||||||
updated(changedProperties) {
|
getCardSize() {
|
||||||
if(changedProperties.has("hass") && this.hass) {
|
let len = 0;
|
||||||
// Run this in a timeout to improve performance
|
if(this.card && this.card.getCardSize)
|
||||||
setTimeout(() => this._getEntities().then((e) => this.entities = e), 0);
|
len = this.card.getCardSize();
|
||||||
}
|
if(len === 1 && this.entities.length)
|
||||||
}
|
len = this.entities.length;
|
||||||
|
if(len === 0 && this._config.filter && this._config.filter.include)
|
||||||
createRenderRoot() {
|
len = Object.keys(this._config.filter.include).length;
|
||||||
return this;
|
return len || 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<card-maker
|
|
||||||
.hass=${this.hass}
|
|
||||||
></card-maker>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCardSize() {
|
|
||||||
let len = 0;
|
|
||||||
if(this.querySelector("card-maker") && this.querySelector("card-maker").getCardSize)
|
|
||||||
len = this.querySelector("card-maker").getCardSize();
|
|
||||||
if(len === 1 && this.entities.length)
|
|
||||||
len = this.entities.length;
|
|
||||||
if(len === 0 && this._config.filter && this._config.filter.include)
|
|
||||||
return Object.keys(this._config.filter.include).length;
|
|
||||||
return len || 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('auto-entities', AutoEntities);
|
customElements.define('auto-entities', AutoEntities);
|
||||||
|
124
src/sort.js
124
src/sort.js
@ -1,66 +1,66 @@
|
|||||||
export function entity_sorter(hass, method) {
|
export function entity_sorter(hass, method) {
|
||||||
if(typeof(method) === "string") {
|
if(typeof(method) === "string") {
|
||||||
method = {method};
|
method = {method};
|
||||||
|
}
|
||||||
|
return function(a, b) {
|
||||||
|
const entityA = typeof(a) === "string"
|
||||||
|
? hass.states[a]
|
||||||
|
: hass.states[a.entity];
|
||||||
|
const entityB = typeof(b) === "string"
|
||||||
|
? hass.states[b]
|
||||||
|
: hass.states[b.entity];
|
||||||
|
|
||||||
|
if(entityA === undefined || entityB === undefined) return 0;
|
||||||
|
|
||||||
|
const [lt, gt] = method.reverse ? [-1, 1] : [1, -1];
|
||||||
|
function compare(_a, _b) {
|
||||||
|
if(method.ignore_case && _a.toLowerCase) _a = _a.toLowerCase();
|
||||||
|
if(method.ignore_case && _b.toLowerCase) _b = _b.toLowerCase();
|
||||||
|
if(_a === undefined && _b === undefined) return 0;
|
||||||
|
if(_a === undefined) return lt;
|
||||||
|
if(_b === undefined) return gt;
|
||||||
|
if(_a < _b) return gt;
|
||||||
|
if(_a > _b) return lt;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return function(a, b) {
|
switch(method.method) {
|
||||||
const entityA = typeof(a) === "string"
|
case "domain":
|
||||||
? hass.states[a]
|
return compare(
|
||||||
: hass.states[a.entity];
|
entityA.entity_id.split(".")[0],
|
||||||
const entityB = typeof(b) === "string"
|
entityB.entity_id.split(".")[0]
|
||||||
? hass.states[b]
|
);
|
||||||
: hass.states[b.entity];
|
case "entity_id":
|
||||||
|
return compare(
|
||||||
if(entityA === undefined || entityB === undefined) return 0;
|
entityA.entity_id,
|
||||||
|
entityB.entity_id
|
||||||
const [lt, gt] = method.reverse ? [-1, 1] : [1, -1];
|
);
|
||||||
function compare(_a, _b) {
|
case "friendly_name":
|
||||||
if(method.ignore_case && _a.toLowerCase) _a = _a.toLowerCase();
|
case "name":
|
||||||
if(method.ignore_case && _b.toLowerCase) _b = _b.toLowerCase();
|
return compare(
|
||||||
if(_a === undefined && _b === undefined) return 0;
|
entityA.attributes.friendly_name || entityA.entity_id.split(".")[1],
|
||||||
if(_a === undefined) return lt;
|
entityB.attributes.friendly_name || entityB.entity_id.split(".")[1]
|
||||||
if(_b === undefined) return gt;
|
);
|
||||||
if(_a < _b) return gt;
|
|
||||||
if(_a > _b) return lt;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
switch(method.method) {
|
|
||||||
case "domain":
|
|
||||||
return compare(
|
|
||||||
entityA.entity_id.split(".")[0],
|
|
||||||
entityB.entity_id.split(".")[0]
|
|
||||||
);
|
|
||||||
case "entity_id":
|
|
||||||
return compare(
|
|
||||||
entityA.entity_id,
|
|
||||||
entityB.entity_id
|
|
||||||
);
|
|
||||||
case "friendly_name":
|
|
||||||
case "name":
|
|
||||||
return compare(
|
|
||||||
entityA.attributes.friendly_name || entityA.entity_id.split(".")[1],
|
|
||||||
entityB.attributes.friendly_name || entityB.entity_id.split(".")[1]
|
|
||||||
);
|
|
||||||
case "state":
|
case "state":
|
||||||
return compare(
|
return compare(
|
||||||
entityA.state,
|
entityA.state,
|
||||||
entityB.state
|
entityB.state
|
||||||
);
|
);
|
||||||
case "attribute":
|
case "attribute":
|
||||||
let _a = entityA.attributes;
|
let _a = entityA.attributes;
|
||||||
let _b = entityB.attributes;
|
let _b = entityB.attributes;
|
||||||
let attr = method.attribute;
|
let attr = method.attribute;
|
||||||
while(attr) {
|
while(attr) {
|
||||||
let k;
|
let k;
|
||||||
[k, attr] = attr.split(":");
|
[k, attr] = attr.split(":");
|
||||||
_a = _a[k];
|
_a = _a[k];
|
||||||
_b = _b[k];
|
_b = _b[k];
|
||||||
if(_a === undefined && _b === undefined) return 0;
|
if(_a === undefined && _b === undefined) return 0;
|
||||||
if(_a === undefined) return lt;
|
if(_a === undefined) return lt;
|
||||||
if(_b === undefined) return gt;
|
if(_b === undefined) return gt;
|
||||||
}
|
}
|
||||||
return compare(_a, _b);
|
return compare(_a, _b);
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user