Love: Card to show entites on picture (#1341)

* Love: Card to show entites on picture

* Lint

* MVP + x

* Feedback

* Add toggle action

* Lint
This commit is contained in:
c727 2018-06-27 03:45:40 +02:00 committed by GitHub
parent aa27ee609d
commit 590bba0aca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 142 additions and 2 deletions

View File

@ -1,7 +1,5 @@
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import './hui-error-card';
import computeStateDomain from '../../../common/entity/compute_state_domain.js';
import createCardElement from '../common/create-card-element';

View File

@ -0,0 +1,140 @@
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
import { PolymerElement } from '@polymer/polymer/polymer-element.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 EventsMixin from '../../../mixins/events-mixin.js';
import LocalizeMixin from '../../../mixins/localize-mixin.js';
/*
* @appliesMixin EventsMixin
* @appliesMixin LocalizeMixin
*/
class HuiPictureElementsCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
static get template() {
return html`
<style>
ha-card {
line-height: 0;
}
#root {
position: relative;
}
#root img {
width: 100%;
}
#root .entity {
white-space: nowrap;
position: absolute;
transform: translate(-50%, -50%);
}
#root .clickable {
cursor: pointer;
padding: 4px;
}
</style>
<ha-card header="[[config.title]]">
<div id="root"></div>
</ha-card>
`;
}
static get properties() {
return {
hass: {
type: Object,
observer: '_hassChanged'
},
config: {
type: Object,
observer: '_configChanged'
}
};
}
getCardSize() {
return 4;
}
_configChanged(config) {
const root = this.$.root;
this._requiresStateObj = [];
while (root.lastChild) {
root.removeChild(root.lastChild);
}
if (config && config.image && config.elements) {
const img = document.createElement('img');
img.src = config.image;
root.appendChild(img);
config.elements.forEach((element) => {
let el;
if (element.type === 'state-badge') {
const entityId = element.entity;
const stateObj = this.hass.states[entityId];
el = document.createElement('state-badge');
el.stateObj = stateObj;
el.addEventListener('click', () => this._handleClick(entityId, element.action === 'toggle'));
el.classList.add('clickable');
el.title = this._computeTooltip(stateObj);
if (element.style) {
Object.keys(element.style).forEach((prop) => {
el.style.setProperty(prop, element.style[prop]);
});
}
this._requiresStateObj.push({ el, entityId });
}
el.classList.add('entity');
root.appendChild(el);
});
}
}
_hassChanged(hass) {
this._requiresStateObj.forEach((element) => {
const { el, entityId } = element;
const stateObj = hass.states[entityId];
el.stateObj = stateObj;
el.title = this._computeTooltip(stateObj);
});
}
_computeTooltip(stateObj) {
return `${computeStateName(stateObj)}: ${computeStateDisplay(this.localize, stateObj)}`;
}
_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 });
} else {
this.fire('hass-more-info', { entityId });
}
}
}
customElements.define('hui-picture-elements-card', HuiPictureElementsCard);

View File

@ -7,6 +7,7 @@ import '../cards/hui-iframe-card.js';
import '../cards/hui-markdown-card.js';
import '../cards/hui-media-control-card.js';
import '../cards/hui-entity-picture-card.js';
import '../cards/hui-picture-elements-card';
import '../cards/hui-picture-glance-card';
import '../cards/hui-plant-status-card.js';
import '../cards/hui-weather-forecast-card';
@ -22,6 +23,7 @@ const CARD_TYPES = [
'iframe',
'markdown',
'media-control',
'picture-elements',
'picture-glance',
'plant-status',
'weather-forecast'