This commit is contained in:
Thomas Lovén 2020-01-12 14:48:39 +01:00
parent c4ab356364
commit e2aab3459f
4 changed files with 69 additions and 38 deletions

View File

@ -15,6 +15,9 @@ resources:
```
## Usage example
**Note:** This is *not* a card. It's a row for an [entities](https://www.home-assistant.io/lovelace/entities/).
![Skärminspelning 2020-01-03 kl 23 03 16 mov](https://user-images.githubusercontent.com/1299821/71752529-b627b000-2e7f-11ea-87ad-3b8f2d2cfe99.gif)
```yaml
type: entities
@ -36,7 +39,7 @@ entities:
## Options
- `icon`, `name`, `state`, `secondary`, `image` selects what icon, name, state, secondary_info text and entity_picture to display respectively.
- `active` if this evaluates to "true", the icon gets the color `--paper-item-icon-active-color`. Otherwise `--paper-item-icon-color`
- `active` if this evaluates to "true", the icon gets the color `--paper-item-icon-active-color`. Otherwise `--paper-item-icon-color`.
- `entity` if this evaluates to an entity id, `icon`, `name`, `state` and `image` will be taken from that entity unless manually overridden.
- `condition` if this is set but does not evaluate to "true", the row is not displayed.
@ -49,6 +52,14 @@ Jinja templates have access to a few special variables. Those are:
- `browser` - the deviceID of the current browser (see [browser_mod](https://github.com/thomasloven/hass-browser_mod)).
- `hash` - the hash part of the current URL.
In evaluated templates the function `_(<key>)` (underscore) will localize the `<key>` to the current language.
E.g. `_(state.binary_sensor.motion.off)` will be replaced with `Clear` if your language is set to English.
To find the available keys, open your browsers console, type in the following and press Enter:
```javascript
document.querySelector("home-assistant").hass.resouces
```
# FAQ
### Why does this look weird?

2
package-lock.json generated
View File

@ -637,7 +637,7 @@
"dev": true
},
"card-tools": {
"version": "github:thomasloven/lovelace-card-tools#8790289006f110d7aefb8cf7ab1bacdad3c620b0",
"version": "github:thomasloven/lovelace-card-tools#90eab9b92abe28e0b329ea9ee2aa7895059beef4",
"from": "github:thomasloven/lovelace-card-tools"
},
"chalk": {

View File

@ -1,5 +1,21 @@
import {LitElement, html, css } from "card-tools/src/lit-element";
import {subscribeRenderTemplate} from "card-tools/src/templates";
import {subscribeRenderTemplate, hasTemplate} from "card-tools/src/templates";
const OPTIONS = [
"icon",
"active",
"name",
"secondary",
"state",
"condition",
"image",
"entity",
// Secret option -
// Set color to a hs-color value ("[<hue>,<saturation>]")
// with hue in the range 0-360 and saturation 0-100.
// Works only if entity is unset and active is set.
"color",
]
class TemplateEntityRow extends LitElement {
@ -14,10 +30,8 @@ class TemplateEntityRow extends LitElement {
this._config = config;
this.state = config;
for(const k of ["icon", "active", "name", "secondary", "state", "condition", "image", "entity"]) {
if(config[k]
&& (String(config[k]).includes("{%") || String(config[k]).includes("{{"))
) {
for(const k of OPTIONS) {
if(config[k] && hasTemplate(config[k])) {
subscribeRenderTemplate(null, (res) => {
this.state[k] = res;
this.requestUpdate();
@ -31,50 +45,54 @@ class TemplateEntityRow extends LitElement {
}
render() {
if (this.state.condition && String(this.state.condition).toLowerCase() !== "true")
if (this.state.condition !== undefined && String(this.state.condition).toLowerCase() !== "true")
return html``;
const entity = this.hass.states[this.state.entity];
const base = this.hass.states[this.state.entity];
const entity = base && JSON.parse(JSON.stringify(base)) || {
entity_id: "light.",
attributes: {icon: "no:icon"},
};
const icon = this.state.icon !== undefined
? this.state.icon || "no:icon"
: entity ? entity.attributes.icon : ""
;
const entity_picture = this.state.image !== undefined
? this.state.image
: entity ? entity.attributes.state_picture : ""
: undefined;
;
const image = this.state.image;
const name = this.state.name !== undefined
? this.state.name
: entity ? entity.attributes.friendly_name || entity.entity_id : ""
: base ? base.attributes.friendly_name || base.entity_id : undefined
;
const secondary = this.state.secondary;
const state = this.state.state !== undefined
? this.state.state
: entity ? entity.state : ""
: entity ? entity.state : undefined
;
const active = String(this.state.active).toLowerCase() === "true";
const active = this.state.active !== undefined
? String(this.state.active).toLowerCase() === "true"
: undefined
;
if(active !== undefined) {
entity.attributes.brightness = 255;
entity.attributes.hs_color = this.state.color !== undefined
? JSON.parse(this.state.color)
: [0,0];
}
return html`
<div id="wrapper">
<state-badge
.hass=${this.hass}
.stateObj=${
{
entity_id: entity ? entity.entity_id : "light.",
state: this.state.active !== undefined
? active ? "on" : "off"
: entity ? entity.state : "off"
,
attributes: {
icon,
entity_picture
}
}
}
style=${active
.stateObj=${entity}
style=${active !== undefined
? active
? "--paper-item-icon-color: var(--paper-item-icon-active-color, #fdd835);"
: "--paper-item-icon-active-color: var(--paper-item-icon-color, #44739e);"
: ""
}
.overrideIcon=${icon}
.overrideImage=${image}
></state-badge>
<div class="flex">
<div

View File

@ -1,17 +1,19 @@
!function(t){var e={};function i(s){if(e[s])return e[s].exports;var n=e[s]={i:s,l:!1,exports:{}};return t[s].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.m=t,i.c=e,i.d=function(t,e,s){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:s})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var s=Object.create(null);if(i.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)i.d(s,n,function(e){return t[e]}.bind(null,n));return s},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=0)}([function(t,e,i){"use strict";i.r(e);const s=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),n=s.prototype.html;s.prototype.css;function r(){return document.querySelector("home-assistant").hass}let a=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const t=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${t()}${t()}-${t()}${t()}`}return localStorage["lovelace-player-device-id"]}();function o(t,e,i){t||(t=r().connection);let s={user:r().user.name,browser:a,hash:location.hash.substr(1)||" ",...i.variables},n=i.template,o=i.entity_ids;return t.subscribeMessage(t=>e(t.result),{type:"render_template",template:n,variables:s,entity_ids:o})}customElements.define("template-entity-row",class extends s{static get properties(){return{hass:{},state:{}}}setConfig(t){this._config=t,this.state=t;for(const e of["icon","active","name","secondary","state","condition","image","entity"])t[e]&&(String(t[e]).includes("{%")||String(t[e]).includes("{{"))&&o(null,t=>{this.state[e]=t,this.requestUpdate()},{template:t[e],variables:{config:t},entity_ids:t.entity_ids})}render(){if(this.state.condition&&"true"!==String(this.state.condition).toLowerCase())return n``;const t=this.hass.states[this.state.entity],e=void 0!==this.state.icon?this.state.icon||"no:icon":t?t.attributes.icon:"",i=void 0!==this.state.image?this.state.image:t?t.attributes.state_picture:"",s=void 0!==this.state.name?this.state.name:t?t.attributes.friendly_name||t.entity_id:"",r=this.state.secondary,a=void 0!==this.state.state?this.state.state:t?t.state:"",o="true"===String(this.state.active).toLowerCase();return n`
!function(t){var e={};function i(s){if(e[s])return e[s].exports;var n=e[s]={i:s,l:!1,exports:{}};return t[s].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.m=t,i.c=e,i.d=function(t,e,s){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:s})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var s=Object.create(null);if(i.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)i.d(s,n,function(e){return t[e]}.bind(null,n));return s},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=0)}([function(t,e,i){"use strict";i.r(e);const s=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),n=s.prototype.html;s.prototype.css;function r(){return document.querySelector("home-assistant").hass}let o=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const t=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${t()}${t()}-${t()}${t()}`}return localStorage["lovelace-player-device-id"]}();function a(t,e,i){t||(t=r().connection);let s={user:r().user.name,browser:o,hash:location.hash.substr(1)||" ",...i.variables},n=i.template,a=i.entity_ids;return t.subscribeMessage(t=>{let i=t.result;i=i.replace(/_\([^)]*\)/g,t=>r().localize(t.substring(2,t.length-1))||t),e(i)},{type:"render_template",template:n,variables:s,entity_ids:a})}const c=["icon","active","name","secondary","state","condition","image","entity","color"];customElements.define("template-entity-row",class extends s{static get properties(){return{hass:{},state:{}}}setConfig(t){this._config=t,this.state=t;for(const i of c)t[i]&&(e=t[i],String(e).includes("{%")||String(e).includes("{{"))&&a(null,t=>{this.state[i]=t,this.requestUpdate()},{template:t[i],variables:{config:t},entity_ids:t.entity_ids});var e}render(){if(void 0!==this.state.condition&&"true"!==String(this.state.condition).toLowerCase())return n``;const t=this.hass.states[this.state.entity],e=t&&JSON.parse(JSON.stringify(t))||{entity_id:"light.",attributes:{icon:"no:icon"}},i=void 0!==this.state.icon?this.state.icon||"no:icon":void 0,s=this.state.image,r=void 0!==this.state.name?this.state.name:t?t.attributes.friendly_name||t.entity_id:void 0,o=this.state.secondary,a=void 0!==this.state.state?this.state.state:e?e.state:void 0,c=void 0!==this.state.active?"true"===String(this.state.active).toLowerCase():void 0;return void 0!==c&&(e.attributes.brightness=255,e.attributes.hs_color=void 0!==this.state.color?JSON.parse(this.state.color):[0,0]),n`
<div id="wrapper">
<state-badge
.hass=${this.hass}
.stateObj=${{entity_id:t?t.entity_id:"light.",state:void 0!==this.state.active?o?"on":"off":t?t.state:"off",attributes:{icon:e,entity_picture:i}}}
style=${o?"--paper-item-icon-color: var(--paper-item-icon-active-color, #fdd835);":""}
.stateObj=${e}
style=${void 0!==c?c?"--paper-item-icon-color: var(--paper-item-icon-active-color, #fdd835);":"--paper-item-icon-active-color: var(--paper-item-icon-color, #44739e);":""}
.overrideIcon=${i}
.overrideImage=${s}
></state-badge>
<div class="flex">
<div
class="info"
>
${s}
<div class="secondary">
${r}
<div class="secondary">
${o}
</div>
</div>
<div class="state">