diff --git a/src/common/const.js b/src/common/const.js
index 9e30ba40f2..3b34a75c28 100644
--- a/src/common/const.js
+++ b/src/common/const.js
@@ -60,14 +60,6 @@ export const DOMAINS_MORE_INFO_NO_HISTORY = [
'scene',
];
-/** States that we consider "on". */
-export const STATES_ON = [
- 'home',
- 'on',
- 'open',
- 'unlocked'
-];
-
/** States that we consider "off". */
export const STATES_OFF = [
'closed',
diff --git a/src/panels/lovelace/cards/hui-glance-card.js b/src/panels/lovelace/cards/hui-glance-card.js
index 95c7cc8186..a43e647762 100644
--- a/src/panels/lovelace/cards/hui-glance-card.js
+++ b/src/panels/lovelace/cards/hui-glance-card.js
@@ -3,7 +3,9 @@ import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import computeStateDisplay from '../../../common/entity/compute_state_display.js';
import computeStateName from '../../../common/entity/compute_state_name.js';
+import createErrorCardConfig from '../common/create-error-card-config.js';
+import './hui-error-card.js';
import '../../../components/entity/state-badge.js';
import '../../../components/ha-card.js';
@@ -44,11 +46,6 @@ class HuiGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
overflow: hidden;
text-overflow: ellipsis;
}
- .error {
- background-color: red;
- color: white;
- text-align: center;
- }
@@ -64,7 +61,7 @@ class HuiGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
- [[_error]]
+
`;
@@ -78,7 +75,7 @@ class HuiGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
type: Array,
computed: '_computeEntities(config)'
},
- _error: String
+ _error: Object
};
}
@@ -87,12 +84,14 @@ class HuiGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
}
_computeEntities(config) {
- if (config && config.entities && Array.isArray(config.entities)) {
- this._error = null;
- return config.entities;
+ if (!config || !config.entities || !Array.isArray(config.entities)) {
+ const error = 'Error in card configuration.';
+ this._error = createErrorCardConfig(error, config);
+ return [];
}
- this._error = 'Error in card configuration.';
- return [];
+
+ this._error = null;
+ return config.entities;
}
_showEntity(item, states) {
diff --git a/src/panels/lovelace/cards/hui-picture-elements-card.js b/src/panels/lovelace/cards/hui-picture-elements-card.js
index 8e74928369..ae47fd80b0 100644
--- a/src/panels/lovelace/cards/hui-picture-elements-card.js
+++ b/src/panels/lovelace/cards/hui-picture-elements-card.js
@@ -5,10 +5,9 @@ import '../../../components/buttons/ha-call-service-button.js';
import '../../../components/entity/state-badge.js';
import '../../../components/ha-card.js';
-import { STATES_ON } from '../../../common/const.js';
-import computeDomain from '../../../common/entity/compute_domain.js';
import computeStateDisplay from '../../../common/entity/compute_state_display.js';
import computeStateName from '../../../common/entity/compute_state_name.js';
+import toggleEntity from '../common/entity/toggle-entity.js';
import EventsMixin from '../../../mixins/events-mixin.js';
import LocalizeMixin from '../../../mixins/localize-mixin.js';
@@ -140,23 +139,7 @@ class HuiPictureElementsCard extends LocalizeMixin(EventsMixin(PolymerElement))
_handleClick(entityId, toggle) {
if (toggle) {
- const turnOn = !STATES_ON.includes(this.hass.states[entityId].state);
- const stateDomain = computeDomain(entityId);
- const serviceDomain = stateDomain === 'lock' || stateDomain === 'cover' ?
- stateDomain : 'homeassistant';
-
- let service;
- switch (stateDomain) {
- case 'lock':
- service = turnOn ? 'unlock' : 'lock';
- break;
- case 'cover':
- service = turnOn ? 'open_cover' : 'close_cover';
- break;
- default:
- service = turnOn ? 'turn_on' : 'turn_off';
- }
- this.hass.callService(serviceDomain, service, { entity_id: entityId });
+ toggleEntity(this.hass, entityId);
} else {
this.fire('hass-more-info', { entityId });
}
diff --git a/src/panels/lovelace/cards/hui-picture-glance-card.js b/src/panels/lovelace/cards/hui-picture-glance-card.js
index 59bc68aadb..5e61c922c8 100644
--- a/src/panels/lovelace/cards/hui-picture-glance-card.js
+++ b/src/panels/lovelace/cards/hui-picture-glance-card.js
@@ -2,14 +2,16 @@ import { html } from '@polymer/polymer/lib/utils/html-tag.js';
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import '@polymer/paper-icon-button/paper-icon-button.js';
+import './hui-error-card.js';
import '../../../components/ha-card.js';
-import { STATES_ON } from '../../../common/const.js';
+import { STATES_OFF } from '../../../common/const.js';
import canToggleState from '../../../common/entity/can_toggle_state.js';
-import computeDomain from '../../../common/entity/compute_domain.js';
import computeStateDisplay from '../../../common/entity/compute_state_display.js';
import computeStateName from '../../../common/entity/compute_state_name.js';
+import createErrorCardConfig from '../common/create-error-card-config.js';
import stateIcon from '../../../common/entity/state_icon.js';
+import toggleEntity from '../common/entity/toggle-entity.js';
import EventsMixin from '../../../mixins/events-mixin.js';
import LocalizeMixin from '../../../mixins/localize-mixin.js';
@@ -25,12 +27,12 @@ class HuiPictureGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
ha-card {
position: relative;
min-height: 48px;
- line-height: 0;
+ overflow: hidden;
}
img {
+ display: block;
width: 100%;
height: auto;
- border-radius: 2px;
}
.box {
@apply --paper-font-common-nowrap;
@@ -43,8 +45,6 @@ class HuiPictureGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
font-size: 16px;
line-height: 40px;
color: white;
- border-bottom-left-radius: 2px;
- border-bottom-right-radius: 2px;
display: flex;
justify-content: space-between;
}
@@ -60,11 +60,6 @@ class HuiPictureGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
iron-icon {
padding: 8px;
}
- .error {
- background-color: red;
- color: white;
- text-align: center;
- }
@@ -97,7 +92,7 @@ class HuiPictureGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
- [[_error]]
+
`;
@@ -112,7 +107,7 @@ class HuiPictureGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
},
_entitiesDialog: Array,
_entitiesService: Array,
- _error: String
+ _error: Object
};
}
@@ -133,7 +128,8 @@ class HuiPictureGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
dialog = config.entities.filter(entity => !service.includes(entity));
}
} else {
- _error = 'Error in card configuration.';
+ const error = 'Error in card configuration.';
+ _error = createErrorCardConfig(error, config);
}
this.setProperties({
_entitiesDialog: dialog,
@@ -151,7 +147,7 @@ class HuiPictureGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
}
_computeClass(entityId, states) {
- return STATES_ON.includes(states[entityId].state) ? 'state-on' : '';
+ return STATES_OFF.includes(states[entityId].state) ? '' : 'state-on';
}
_computeTooltip(entityId, states) {
@@ -164,24 +160,7 @@ class HuiPictureGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
_callService(ev) {
const entityId = ev.model.item;
- let domain = computeDomain(entityId);
- const turnOn = !STATES_ON.includes(this.hass.states[entityId].state);
- let service;
- switch (domain) {
- case 'lock':
- service = turnOn ? 'unlock' : 'lock';
- break;
- case 'cover':
- service = turnOn ? 'open_cover' : 'close_cover';
- break;
- case 'group':
- domain = 'homeassistant';
- service = turnOn ? 'turn_on' : 'turn_off';
- break;
- default:
- service = turnOn ? 'turn_on' : 'turn_off';
- }
- this.hass.callService(domain, service, { entity_id: entityId });
+ toggleEntity(this.hass, entityId);
}
}
diff --git a/src/panels/lovelace/common/entity/toggle-entity.js b/src/panels/lovelace/common/entity/toggle-entity.js
new file mode 100644
index 0000000000..dfaf251ede
--- /dev/null
+++ b/src/panels/lovelace/common/entity/toggle-entity.js
@@ -0,0 +1,7 @@
+import { STATES_OFF } from '../../../../common/const.js';
+import turnOnOffEntity from './turn-on-off-entity.js';
+
+export default function toggleEntity(hass, entityId) {
+ const turnOn = STATES_OFF.includes(hass.states[entityId].state);
+ turnOnOffEntity(hass, entityId, turnOn);
+}
diff --git a/src/panels/lovelace/common/entity/turn-on-off-entities.js b/src/panels/lovelace/common/entity/turn-on-off-entities.js
new file mode 100644
index 0000000000..e24f4ee366
--- /dev/null
+++ b/src/panels/lovelace/common/entity/turn-on-off-entities.js
@@ -0,0 +1,33 @@
+import { STATES_OFF } from '../../../../common/const.js';
+import computeDomain from '../../../../common/entity/compute_domain.js';
+
+export default function turnOnOffEntities(hass, entityIds, turnOn = true) {
+ const domainsToCall = {};
+ entityIds.forEach((entityId) => {
+ if ((STATES_OFF.includes(hass.states[entityId].state)) === turnOn) {
+ const stateDomain = computeDomain(entityId);
+ const serviceDomain = ['cover', 'lock'].includes(stateDomain) ?
+ stateDomain : 'homeassistant';
+
+ if (!(serviceDomain in domainsToCall)) domainsToCall[serviceDomain] = [];
+ domainsToCall[serviceDomain].push(entityId);
+ }
+ });
+
+ Object.keys(domainsToCall).forEach((domain) => {
+ let service;
+ switch (domain) {
+ case 'lock':
+ service = turnOn ? 'unlock' : 'lock';
+ break;
+ case 'cover':
+ service = turnOn ? 'open_cover' : 'close_cover';
+ break;
+ default:
+ service = turnOn ? 'turn_on' : 'turn_off';
+ }
+
+ const entities = domainsToCall[domain];
+ hass.callService(domain, service, { entity_id: entities });
+ });
+}
diff --git a/src/panels/lovelace/common/entity/turn-on-off-entity.js b/src/panels/lovelace/common/entity/turn-on-off-entity.js
new file mode 100644
index 0000000000..e61d8e8a48
--- /dev/null
+++ b/src/panels/lovelace/common/entity/turn-on-off-entity.js
@@ -0,0 +1,20 @@
+import computeDomain from '../../../../common/entity/compute_domain.js';
+
+export default function turnOnOffEntity(hass, entityId, turnOn = true) {
+ const stateDomain = computeDomain(entityId);
+ const serviceDomain = stateDomain === 'group' ? 'homeassistant' : stateDomain;
+
+ let service;
+ switch (stateDomain) {
+ case 'lock':
+ service = turnOn ? 'unlock' : 'lock';
+ break;
+ case 'cover':
+ service = turnOn ? 'open_cover' : 'close_cover';
+ break;
+ default:
+ service = turnOn ? 'turn_on' : 'turn_off';
+ }
+
+ hass.callService(serviceDomain, service, { entity_id: entityId });
+}
diff --git a/src/panels/lovelace/components/hui-entities-toggle.js b/src/panels/lovelace/components/hui-entities-toggle.js
index d156a3b38b..e291f0d72a 100644
--- a/src/panels/lovelace/components/hui-entities-toggle.js
+++ b/src/panels/lovelace/components/hui-entities-toggle.js
@@ -3,8 +3,8 @@ import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import '@polymer/paper-toggle-button/paper-toggle-button.js';
import canToggleState from '../../../common/entity/can_toggle_state.js';
-import computeDomain from '../../../common/entity/compute_domain.js';
-import { STATES_ON } from '../../../common/const.js';
+import turnOnOffEntities from '../common/entity/turn-on-off-entities.js';
+import { STATES_OFF } from '../../../common/const.js';
class HuiEntitiesToggle extends PolymerElement {
static get template() {
@@ -38,46 +38,18 @@ class HuiEntitiesToggle extends PolymerElement {
};
}
- _computeToggleEntities(hass, entities) {
- return entities.filter(entity => (entity in hass.states ?
- canToggleState(hass, hass.states[entity]) : false));
+ _computeToggleEntities(hass, entityIds) {
+ return entityIds.filter(entityId => (entityId in hass.states ?
+ canToggleState(hass, hass.states[entityId]) : false));
}
- _computeIsChecked(hass, entities) {
- return entities.some(entity => STATES_ON.includes(hass.states[entity].state));
+ _computeIsChecked(hass, entityIds) {
+ return entityIds.some(entityId => !STATES_OFF.includes(hass.states[entityId].state));
}
_callService(ev) {
const turnOn = ev.target.checked;
- const toCall = {};
-
- this.entities.forEach((entity) => {
- if ((STATES_ON.includes(this.hass.states[entity].state)) !== turnOn) {
- const stateDomain = computeDomain(entity);
- const serviceDomain = stateDomain === 'lock' || stateDomain === 'cover' ?
- stateDomain : 'homeassistant';
-
- if (!(serviceDomain in toCall)) toCall[serviceDomain] = [];
- toCall[serviceDomain].push(entity);
- }
- });
-
- Object.keys(toCall).forEach((domain) => {
- let service;
- switch (domain) {
- case 'lock':
- service = turnOn ? 'unlock' : 'lock';
- break;
- case 'cover':
- service = turnOn ? 'open_cover' : 'close_cover';
- break;
- default:
- service = turnOn ? 'turn_on' : 'turn_off';
- }
-
- const entities = toCall[domain];
- this.hass.callService(domain, service, { entity_id: entities });
- });
+ turnOnOffEntities(this.hass, this._toggleEntities, turnOn);
}
}