diff --git a/src/components/entity/ha-entity-toggle.js b/src/components/entity/ha-entity-toggle.js
index 5d75d15cc7..f79bdd3a17 100644
--- a/src/components/entity/ha-entity-toggle.js
+++ b/src/components/entity/ha-entity-toggle.js
@@ -122,13 +122,16 @@ class HaEntityToggle extends PolymerElement {
if (stateDomain === 'lock') {
serviceDomain = 'lock';
- service = turnOn ? 'lock' : 'unlock';
+ service = turnOn ? 'unlock' : 'lock';
} else if (stateDomain === 'cover') {
serviceDomain = 'cover';
- service = turnOn ? 'open' : 'close';
- } else {
+ service = turnOn ? 'open_cover' : 'close_cover';
+ } else if (stateDomain === 'group') {
serviceDomain = 'homeassistant';
service = turnOn ? 'turn_on' : 'turn_off';
+ } else {
+ serviceDomain = stateDomain;
+ service = turnOn ? 'turn_on' : 'turn_off';
}
const currentState = this.stateObj;
diff --git a/src/panels/lovelace/cards/hui-entities-card.js b/src/panels/lovelace/cards/hui-entities-card.js
index e7d4033104..84811652f3 100644
--- a/src/panels/lovelace/cards/hui-entities-card.js
+++ b/src/panels/lovelace/cards/hui-entities-card.js
@@ -7,6 +7,7 @@ import computeDomain from '../../../common/entity/compute_domain.js';
import { DOMAINS_HIDE_MORE_INFO } from '../../../common/const.js';
import '../../../components/ha-card.js';
+import '../components/hui-entities-toggle.js';
// just importing this now as shortcut to import correct state-card-*
import '../../../state-summary/state-card-content.js';
@@ -36,6 +37,8 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) {
line-height: 40px;
color: var(--primary-text-color);
padding: 4px 0 12px;
+ display: flex;
+ justify-content: space-between;
}
.header .name {
@apply --paper-font-common-nowrap;
@@ -48,6 +51,9 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) {
@@ -81,6 +87,10 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) {
return config.title;
}
+ _showHeaderToggle(show) {
+ return show !== false;
+ }
+
_configChanged(config) {
const root = this.$.states;
diff --git a/src/panels/lovelace/cards/hui-entity-picture-card.js b/src/panels/lovelace/cards/hui-entity-picture-card.js
index c40b82f025..3fc2854e3e 100644
--- a/src/panels/lovelace/cards/hui-entity-picture-card.js
+++ b/src/panels/lovelace/cards/hui-entity-picture-card.js
@@ -124,17 +124,17 @@ class HuiPictureCard extends LocalizeMixin(PolymerElement) {
if (domain === 'weblink') {
window.open(this.hass.states[entityId].state);
} else {
- const isOn = STATES_ON.includes(this.hass.states[entityId].state);
+ const turnOn = !STATES_ON.includes(this.hass.states[entityId].state);
let service;
switch (domain) {
case 'lock':
- service = isOn ? 'unlock' : 'lock';
+ service = turnOn ? 'unlock' : 'lock';
break;
case 'cover':
- service = isOn ? 'close' : 'open';
+ service = turnOn ? 'open_cover' : 'close_cover';
break;
default:
- service = isOn ? 'turn_off' : 'turn_on';
+ service = turnOn ? 'turn_on' : 'turn_off';
}
this.hass.callService(domain, service, { entity_id: entityId });
}
diff --git a/src/panels/lovelace/components/hui-entities-toggle.js b/src/panels/lovelace/components/hui-entities-toggle.js
new file mode 100644
index 0000000000..d156a3b38b
--- /dev/null
+++ b/src/panels/lovelace/components/hui-entities-toggle.js
@@ -0,0 +1,84 @@
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+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';
+
+class HuiEntitiesToggle extends PolymerElement {
+ static get template() {
+ return html`
+
+
+
+
+`;
+ }
+
+ static get properties() {
+ return {
+ hass: Object,
+ entities: Array,
+ _toggleEntities: {
+ type: Array,
+ computed: '_computeToggleEntities(hass, entities)'
+ }
+ };
+ }
+
+ _computeToggleEntities(hass, entities) {
+ return entities.filter(entity => (entity in hass.states ?
+ canToggleState(hass, hass.states[entity]) : false));
+ }
+
+ _computeIsChecked(hass, entities) {
+ return entities.some(entity => STATES_ON.includes(hass.states[entity].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 });
+ });
+ }
+}
+
+customElements.define('hui-entities-toggle', HuiEntitiesToggle);