forked from custom-cards/monster-card
-
Notifications
You must be signed in to change notification settings - Fork 0
/
monster-card.js
123 lines (108 loc) · 4.2 KB
/
monster-card.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
class MonsterCard extends HTMLElement {
_getEntities(hass, filters) {
function _filterEntityId(stateObj, pattern) {
if (pattern.indexOf('*') === -1) {
return stateObj.entity_id === pattern;
}
const regEx = new RegExp(`^${pattern.replace(/\*/g, '.*')}$`, 'i');
return stateObj.entity_id.search(regEx) === 0;
}
function _filterName(stateObj, pattern) {
let compareEntity = stateObj.attributes.title ? stateObj.attributes.title : stateObj.attributes.friendly_name;
if (!compareEntity) compareEntity = stateObj.entity_id;
if (pattern.indexOf('*') === -1) {
return compareEntity === pattern;
}
const regEx = new RegExp(`^${pattern.replace(/\*/g, '.*')}$`, 'i');
return compareEntity.search(regEx) === 0;
}
// Allows '< 300' in b
function _complexCompare(a, b) {
const _compare = {
'>': (x, y) => x > y,
'<': (x, y) => x < y,
'<=': (x, y) => x <= y,
'>=': (x, y) => x >= y,
'=': (x, y) => x === y,
};
let operator = '=';
let y = b;
let x = a;
if (!isNaN(a) && typeof (b) == 'string'
&& b.split(" ").length > 1) {
[operator, y] = b.split(' ', 2);
x = parseFloat(a);
}
return _compare[operator](x, y);
}
const entities = new Map();
filters.forEach((filter) => {
const filters = [];
if (filter.domain) {
filters.push(stateObj => stateObj.entity_id.split('.', 1)[0] === filter.domain);
}
if (filter.attributes) {
Object.keys(filter.attributes).forEach(key => {
filters.push(stateObj => _complexCompare(stateObj.attributes[key], filter.attributes[key]));
});
}
if (filter.entity_id) {
filters.push(stateObj => _filterEntityId(stateObj, filter.entity_id));
}
if (filter.name) {
filters.push(stateObj => _filterName(stateObj, filter.name));
}
if (filter.state) {
filters.push(stateObj => _complexCompare(stateObj.state, filter.state));
}
const options = filter.options ? filter.options : {}
Object.keys(hass.states).sort().forEach(key => {
if (filters.every(filterFunc => filterFunc(hass.states[key]))) {
const dynOptions = JSON.parse(JSON.stringify(options).replace(/this.entity_id/g,hass.states[key].entity_id));
entities.set(hass.states[key].entity_id, Object.assign({ "entity": hass.states[key].entity_id }, dynOptions));
}
});
});
return Array.from(entities.values());
}
setConfig(config) {
if (!config.filter.include || !Array.isArray(config.filter.include)) {
throw new Error('Please define filters');
}
if (this.lastChild) this.removeChild(this.lastChild);
const cardConfig = Object.assign({}, config);
if (!cardConfig.card) cardConfig.card = {};
if (config.card.entities) delete config.card.entities;
if (!cardConfig.card.type) cardConfig.card.type = 'entities';
const element = document.createElement(`hui-${cardConfig.card.type}-card`);
this.appendChild(element);
this._config = cardConfig;
}
set hass(hass) {
const config = this._config;
let entities = this._getEntities(hass, config.filter.include);
if (config.filter.exclude) {
const excludeEntities = this._getEntities(hass, config.filter.exclude).map(entity => entity.entity);
entities = entities.filter(entity => !excludeEntities.includes(entity.entity));
}
if (entities.length === 0 && config.show_empty === false) {
this.style.display = 'none';
} else {
if (config.when && (hass.states[config.when.entity].state == config.when.state) || !config.when) {
this.style.display = 'block';
} else {
this.style.display = 'none';
}
}
if (!config.card.entities || config.card.entities.length !== entities.length ||
!config.card.entities.every((value, index) => value.entity === entities[index].entity)) {
config.card.entities = entities;
this.lastChild.setConfig(config.card);
}
this.lastChild.hass = hass;
}
getCardSize() {
return 'getCardSize' in this.lastChild ? this.lastChild.getCardSize() : 1;
}
}
customElements.define('monster-card', MonsterCard);