Initial commit
This commit is contained in:
commit
39ccb78490
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
template-entity-row.js binary
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules/
|
21
LICENSE.txt
Normal file
21
LICENSE.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Thomas Lovén
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
57
README.md
Normal file
57
README.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# template-entity-row
|
||||||
|
|
||||||
|
[](https://github.com/custom-components/hacs)
|
||||||
|
|
||||||
|
Display whatever you want in an entities card row.
|
||||||
|
|
||||||
|
For installation instructions [see this guide](https://github.com/thomasloven/hass-config/wiki/Lovelace-Plugins).
|
||||||
|
|
||||||
|
Install `template-entity-row.js` as a `module`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
resources:
|
||||||
|
- url: /local/template-entity-row.js
|
||||||
|
type: module
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage example
|
||||||
|

|
||||||
|
```yaml
|
||||||
|
type: entities
|
||||||
|
title: Default
|
||||||
|
entities:
|
||||||
|
- light.bed_light
|
||||||
|
- entity: input_boolean.car_home
|
||||||
|
- type: custom:template-entity-row
|
||||||
|
icon: mdi:lamp
|
||||||
|
name: "The light is {{states('light.bed_light')}} but nobody's"
|
||||||
|
state: "{% if is_state('input_boolean.car_home', 'on')%} home {% else %} away {% endif %}"
|
||||||
|
secondary: "It's {{states('sensor.time')}}"
|
||||||
|
active: "{{ is_state('light.bed_light', 'off') }}"
|
||||||
|
- type: custom:template-entity-row
|
||||||
|
icon: mdi:car
|
||||||
|
name: Hi there
|
||||||
|
condition: "{{is_state('input_boolean.car_home', 'on')}}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
- `icon`, `name`, `state`, `secondary` selects what icon, name, state and secondary_info text to display respectively
|
||||||
|
- `active` if this evaluates to "true", the icon gets the color `--paper-item-icon-active-color`. Otherwise `--paper-item-icon-color`
|
||||||
|
- `condition` if this is set but does not evaluate to "true", the row is not displayed.
|
||||||
|
|
||||||
|
All options accept [jinja2 templates](https://www.home-assistant.io/docs/configuration/templating/).
|
||||||
|
|
||||||
|
Jinja templates have access to a few special variables. Those are:
|
||||||
|
|
||||||
|
- `config` - an object containing the card, entity row or glance button configuration
|
||||||
|
- `user` - the username of the currently logged in user
|
||||||
|
- `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.
|
||||||
|
|
||||||
|
# FAQ
|
||||||
|
|
||||||
|
### Why does this look weird?
|
||||||
|
Because you're not using it correctly. This is **not** a card. It's an entity row, and is meant to be used *inside* the [entities card](https://www.home-assistant.io/lovelace/entities/)
|
||||||
|
|
||||||
|
---
|
||||||
|
<a href="https://www.buymeacoffee.com/uqD6KHCdJ" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/white_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>
|
4
hacs.json
Normal file
4
hacs.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "template-entity-row",
|
||||||
|
"render_readme": true
|
||||||
|
}
|
4078
package-lock.json
generated
Normal file
4078
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
package.json
Normal file
25
package.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "template-entity-row",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack",
|
||||||
|
"watch": "webpack --watch --mode=development",
|
||||||
|
"update-card-tools": "npm uninstall card-tools && npm install thomasloven/lovelace-card-tools"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "github.com:thomasloven/lovelace-template-entity-row"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "Thomas Lovén",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"webpack": "^4.41.5",
|
||||||
|
"webpack-cli": "^3.3.10"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"card-tools": "github:thomasloven/lovelace-card-tools"
|
||||||
|
}
|
||||||
|
}
|
80
src/main.js
Normal file
80
src/main.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import {LitElement, html, css } from "card-tools/src/lit-element";
|
||||||
|
import {subscribeRenderTemplate} from "card-tools/src/templates";
|
||||||
|
|
||||||
|
class TemplateEntityRow extends LitElement {
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: {},
|
||||||
|
_config: {},
|
||||||
|
state: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
this._config = config;
|
||||||
|
this.state = {
|
||||||
|
icon: "",
|
||||||
|
active: "",
|
||||||
|
name: "",
|
||||||
|
secondary: "",
|
||||||
|
state: "",
|
||||||
|
...config,
|
||||||
|
};
|
||||||
|
|
||||||
|
for(const k of ["icon", "active", "name", "secondary", "state", "condition"]) {
|
||||||
|
if(config[k]
|
||||||
|
&& (String(config[k]).includes("{%") || String(config[k]).includes("{{"))
|
||||||
|
) {
|
||||||
|
subscribeRenderTemplate(null, (res) => {
|
||||||
|
this.state[k] = res;
|
||||||
|
this.requestUpdate();
|
||||||
|
}, {
|
||||||
|
template: config[k],
|
||||||
|
entity_ids: config.entity_ids,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this._config.condition && String(this.state.condition).toLowerCase() !== "true")
|
||||||
|
return html``;
|
||||||
|
const active = String(this.state.active).toLowerCase();
|
||||||
|
return html`
|
||||||
|
<div id="wrapper">
|
||||||
|
<ha-icon
|
||||||
|
.icon=${this.state.icon}
|
||||||
|
style="
|
||||||
|
color: ${active === "true"
|
||||||
|
? "var(--paper-item-icon-active-color)"
|
||||||
|
: "var(--paper-item-icon-color)"
|
||||||
|
};
|
||||||
|
"
|
||||||
|
></ha-icon>
|
||||||
|
<div class="flex">
|
||||||
|
<div
|
||||||
|
class="info"
|
||||||
|
>
|
||||||
|
${this.state.name}
|
||||||
|
<div class="secondary">
|
||||||
|
${this.state.secondary}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
${this.state.state}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
const HuiGenericEntityRow = customElements.get('hui-generic-entity-row');
|
||||||
|
let style = HuiGenericEntityRow.styles;
|
||||||
|
style.cssText = style.cssText
|
||||||
|
.replace(":host", "#wrapper")
|
||||||
|
.replace("state-badge", "ha-icon");
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("template-entity-row", TemplateEntityRow);
|
21
template-entity-row.js
Normal file
21
template-entity-row.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);const r=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),i=r.prototype.html;r.prototype.css;function o(){return document.querySelector("home-assistant").hass}let s=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${e()}${e()}-${e()}${e()}`}return localStorage["lovelace-player-device-id"]}();function a(e,t,n){e||(e=o().connection);let r={user:o().user.name,browser:s,hash:location.hash.substr(1)||" ",...n.variables},i=n.template,a=n.entity_ids;return e.subscribeMessage(e=>t(e.result),{type:"render_template",template:i,variables:r,entity_ids:a})}customElements.define("template-entity-row",class extends r{static get properties(){return{hass:{},_config:{},state:{}}}setConfig(e){this._config=e,this.state={icon:"",active:"",name:"",secondary:"",state:"",...e};for(const t of["icon","active","name","secondary","state","condition"])e[t]&&(String(e[t]).includes("{%")||String(e[t]).includes("{{"))&&a(null,e=>{this.state[t]=e,this.requestUpdate()},{template:e[t],entity_ids:e.entity_ids})}render(){if(this._config.condition&&"true"!==String(this.state.condition).toLowerCase())return i``;const e=String(this.state.active).toLowerCase();return i`
|
||||||
|
<div id="wrapper">
|
||||||
|
<ha-icon
|
||||||
|
.icon=${this.state.icon}
|
||||||
|
style="
|
||||||
|
color: ${"true"===e?"var(--paper-item-icon-active-color)":"var(--paper-item-icon-color)"};
|
||||||
|
"
|
||||||
|
></ha-icon>
|
||||||
|
<div class="flex">
|
||||||
|
<div
|
||||||
|
class="info"
|
||||||
|
>
|
||||||
|
${this.state.name}
|
||||||
|
<div class="secondary">
|
||||||
|
${this.state.secondary}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
${this.state.state}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`}static get styles(){let e=customElements.get("hui-generic-entity-row").styles;return e.cssText=e.cssText.replace(":host","#wrapper").replace("state-badge","ha-icon"),e}})}]);
|
10
webpack.config.js
Normal file
10
webpack.config.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: './src/main.js',
|
||||||
|
mode: 'production',
|
||||||
|
output: {
|
||||||
|
filename: 'template-entity-row.js',
|
||||||
|
path: path.resolve(__dirname)
|
||||||
|
}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user