Skip to content

Commit

Permalink
Templatable entities and wait for config
Browse files Browse the repository at this point in the history
Fixes #33
Fixes #31
  • Loading branch information
iantrich committed Jun 9, 2020
1 parent 9286c82 commit 2a5821f
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 25 deletions.
10 changes: 9 additions & 1 deletion .devcontainer/configuration.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
default_config:
lovelace:
mode: yaml
demo:
resources:
- url: http://127.0.0.1:5000/config-template-card.js
type: module
demo:
sensor:
- platform: template
sensors:
light:
value_template: light.bed_light
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// See https://aka.ms/vscode-remote/devcontainer.json for format details.
{
"name": "Config Template Card Development",
"image": "ludeeus/devcontainer:monster-stable",
"image": "ludeeus/container:monster",
"context": "..",
"appPort": ["5000:5000", "9123:8123"],
"postCreateCommand": "npm install",
Expand Down
18 changes: 12 additions & 6 deletions .devcontainer/ui-lovelace.yaml
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
resources:
- url: http://127.0.0.1:5000/config-template-card.js
type: module
views:
- cards:
- type: 'custom:config-template-card'
variables:
- states['sensor.light'].state
entities:
- '${vars[0]}'
card:
type: light
entity: '${vars[0]}'
name: "${states[vars[0]].state === 'on' ? 'Light On' : 'Light Off'}"
- type: 'custom:config-template-card'
variables:
- states['light.bed_light'].state
- states['cover.garage_door'].state
entities:
- light.bed_light
- cover.garage_door
- alarm_control_panel.ha_alarm
- alarm_control_panel.alarm
- climate.ecobee
card:
type: "${vars[0] === 'on' ? 'custom:hui-glance-card' : 'custom:hui-entities-card'}"
entities:
- entity: alarm_control_panel.ha_alarm
name: "${vars[1] === 'open' && states['alarm_control_panel.ha_alarm'].state === 'armed_home' ? 'Close the garage!' : ''}"
- entity: alarm_control_panel.alarm
name: "${vars[1] === 'open' && states['alarm_control_panel.alarm'].state === 'armed_home' ? 'Close the garage!' : ''}"
- entity: binary_sensor.basement_floor_wet
- entity: climate.ecobee
name: "${states['climate.ecobee'].attributes.current_temperature > 22 ? 'Cozy' : 'Too Hot/Cold'}"
Expand Down
34 changes: 26 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

This card is for [Lovelace](https://www.home-assistant.io/lovelace) on [Home Assistant](https://www.home-assistant.io/) that allows you to use pretty much any valid Javascript on the hass object in your configuration

## Minimum Home Assistant Version

Home Assistant version 0.110.0 or higher is required as of release 1.2.0 of config-template-card

## Support

Hey dude! Help me out for a couple of :beers: or a :coffee:!
Expand All @@ -29,8 +33,8 @@ Use [HACS](https://hacs.xyz) or follow this [guide](https://github.com/thomaslov

```yaml
resources:
url: /local/config-template-card.js
type: module
- url: /local/config-template-card.js
type: module
```
## Options
Expand All @@ -39,7 +43,7 @@ resources:
| --------- | ------ | ------------ | ----------------------------------------------------------------------------------------------------- |
| type | string | **Required** | `custom:config-template-card` |
| card | object | **Required** | Card object |
| entities | list | **Required** | List of entity strings that should be watched for updates |
| entities | list | **Required** | List of entity strings that should be watched for updates. Templates can be used here |
| variables | list | **Optional** | List of variables, which can be templates, that can be used in your `config` and indexed using `vars` |

### Available variables for templating
Expand All @@ -52,20 +56,20 @@ resources:
| `vars` | Defined by `variables` configuration and accessible in your templates starting at the 0th index as your firstly defined variable to help clean up your templates |

```yaml
type: "custom:config-template-card"
type: 'custom:config-template-card'
variables:
- states['light.bed_light'].state
- states['cover.garage_door'].state
entities:
- light.bed_light
- cover.garage_door
- alarm_control_panel.ha_alarm
- alarm_control_panel.alarm
- climate.ecobee
card:
type: "${vars[0] === 'on' ? 'custom:hui-glance-card' : 'custom:hui-entities-card'}"
entities:
- entity: alarm_control_panel.ha_alarm
name: "${vars[1] === 'open' && states['alarm_control_panel.ha_alarm'].state === 'armed_home' ? 'Close the garage!' : ''}"
- entity: alarm_control_panel.alarm
name: "${vars[1] === 'open' && states['alarm_control_panel.alarm'].state === 'armed_home' ? 'Close the garage!' : ''}"
- entity: binary_sensor.basement_floor_wet
- entity: climate.ecobee
name: "${states['climate.ecobee'].attributes.current_temperature > 22 ? 'Cozy' : 'Too Hot/Cold'}"
Expand All @@ -74,7 +78,21 @@ card:
icon: "${vars[1] === 'open' ? 'mdi:hotel' : '' }"
```

### Note: All templates must be enclosed by `${}` and card type must custom even for core. e.g. custom:hui-shopping-list-card
Templated entities example

```yaml
type: 'custom:config-template-card'
variables:
- states['sensor.light'].state
entities:
- '${vars[0]}'
card:
type: light
entity: '${vars[0]}'
name: "${states[vars[0]].state === 'on' ? 'Light On' : 'Light Off'}"
```

### Note: All templates must be enclosed by `${}`

[Troubleshooting](https://github.com/thomasloven/hass-config/wiki/Lovelace-Plugins)

Expand Down
7 changes: 4 additions & 3 deletions hacs.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"name": "Config Template Card",
"render_readme": true
}
"name": "Config Template Card",
"render_readme": true,
"homeassistant": "0.110.0"
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "config-template-card",
"version": "1.1.2",
"version": "1.2.0",
"description": "Lovelace config-template-card",
"keywords": [
"home-assistant",
Expand Down
29 changes: 25 additions & 4 deletions src/config-template-card.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { LitElement, html, customElement, property, TemplateResult, PropertyValues } from 'lit-element';
import deepClone from 'deep-clone-simple';
import { HomeAssistant, createThing } from 'custom-card-helpers';
import { HomeAssistant } from 'custom-card-helpers';

import { ConfigTemplateConfig } from './types';
import { CARD_VERSION } from './const';
Expand All @@ -18,6 +18,7 @@ export class ConfigTemplateCard extends LitElement {
@property() public hass?: HomeAssistant;
@property() private _config?: ConfigTemplateConfig;
@property() private _helpers?: any;
private _initialized = false;

public setConfig(config: ConfigTemplateConfig): void {
if (!config) {
Expand All @@ -42,6 +43,10 @@ export class ConfigTemplateCard extends LitElement {
}

protected shouldUpdate(changedProps: PropertyValues): boolean {
if (!this._initialized) {
this._initialize();
}

if (changedProps.has('_config')) {
return true;
}
Expand All @@ -52,7 +57,12 @@ export class ConfigTemplateCard extends LitElement {
if (oldHass) {
let changed = false;
this._config.entities.forEach(entity => {
changed = changed || Boolean(this.hass && oldHass.states[entity] !== this.hass.states[entity]);
changed =
changed ||
Boolean(
this.hass &&
oldHass.states[this._evaluateTemplate(entity)] !== this.hass.states[this._evaluateTemplate(entity)],
);
});

return changed;
Expand All @@ -63,21 +73,28 @@ export class ConfigTemplateCard extends LitElement {
}

protected render(): TemplateResult | void {
if (!this._config || !this.hass) {
if (!this._config || !this.hass || !this._helpers) {
return html``;
}

let cardConfig = deepClone(this._config.card);
cardConfig = this._evaluateConfig(cardConfig);

const element = this._helpers ? this._helpers.createCardElement(cardConfig) : createThing(cardConfig);
const element = this._helpers.createCardElement(cardConfig);
element.hass = this.hass;

return html`
${element}
`;
}

private _initialize(): void {
if (this.hass === undefined) return;
if (this._config === undefined) return;
if (this._helpers === undefined) return;
this._initialized = true;
}

private async loadCardHelpers(): Promise<void> {
this._helpers = await (window as any).loadCardHelpers();
}
Expand Down Expand Up @@ -119,6 +136,10 @@ export class ConfigTemplateCard extends LitElement {
}

private _evaluateTemplate(template: string): string {
if (!template.includes('${')) {
return template;
}

/* eslint-disable @typescript-eslint/no-unused-vars */
const user = this.hass ? this.hass.user : undefined;
const states = this.hass ? this.hass.states : undefined;
Expand Down
2 changes: 1 addition & 1 deletion src/const.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const CARD_VERSION = '1.1.2';
export const CARD_VERSION = '1.2.0';

0 comments on commit 2a5821f

Please sign in to comment.