Skip to content

Commit

Permalink
Changed card creation to use lovelace helper (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulonutor authored Jun 30, 2023
1 parent fb39c53 commit 6e9bb2a
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 114 deletions.
4 changes: 4 additions & 0 deletions info.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{% if installed %}

### Features
{% if version_installed.replace("v", "").replace(".","") | int < 10725 %}
- Fixed `broken card creation`
{% endif %}

{% if version_installed.replace("v", "").replace(".","") | int < 10724 %}
- Added `support for stack, grid and glance cards`
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "room-card",
"version": "1.07.24",
"version": "1.07.25",
"description": "Show entities in Home Assistant's Lovelace UI",
"keywords": [
"home-assistant",
Expand Down
16 changes: 8 additions & 8 deletions room-card.js

Large diffs are not rendered by default.

Binary file modified room-card.js.gz
Binary file not shown.
56 changes: 43 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { CSSResult, html, LitElement, PropertyValues, TemplateResult } from 'lit';
import { property, customElement } from 'lit/decorators.js';
import { HomeAssistant } from 'custom-card-helpers';
import { HomeAssistant, LovelaceCard, LovelaceCardConfig, createThing } from 'custom-card-helpers';

import { checkConfig, entityStyles, renderEntitiesRow, renderInfoEntity, renderRows, renderTitle } from './entity';
import { getEntityIds, hasConfigOrEntitiesChanged, mapStateObject, createCardElement } from './util';
import { getEntityIds, hasConfigOrEntitiesChanged, mapStateObject } from './util';
import { hideIfCard } from './hide';
import { style } from './styles';
import { HomeAssistantEntity, RoomCardConfig, RoomCardEntity, RoomCardLovelaceCardConfig, RoomCardRow } from './types/room-card-types';
import * as packageJson from '../package.json';
Expand All @@ -17,9 +18,9 @@ console.info(
/* eslint-disable @typescript-eslint/no-explicit-any */
(window as any).customCards = (window as any).customCards || [];
(window as any).customCards.push({
type: 'room-card',
name: 'Room card',
preview: false,
type: 'room-card',
name: 'Room card',
preview: false,
description: 'Show multiple entity states, attributes and icons in a single card in Home Assistant\'s Lovelace UI',
});
/* eslint-enable @typescript-eslint/no-explicit-any */
Expand All @@ -28,19 +29,25 @@ console.info(
export default class RoomCard extends LitElement {
@property() _hass?: HomeAssistant;
@property() config?: RoomCardConfig;

private entity: RoomCardEntity | undefined;
private info_entities: RoomCardEntity[] = [];
private entities: RoomCardEntity[] = [];
private rows: RoomCardRow[] = [];
private stateObj: HomeAssistantEntity | undefined;
private _refCards: RoomCardLovelaceCardConfig[] = [];

setConfig(config: RoomCardConfig) {
private _refCards: LovelaceCard[] = [];
private _helpers: { createCardElement(config: LovelaceCardConfig): LovelaceCard };

checkConfig(config);
async setConfig(config: RoomCardConfig) {
checkConfig(config);

this.config = { ...config, entityIds: getEntityIds(config) };

/* eslint-disable @typescript-eslint/no-explicit-any */
if ((window as any).loadCardHelpers) {
this._helpers = await (window as any).loadCardHelpers();
}
/* eslint-enable @typescript-eslint/no-explicit-any */
}

protected shouldUpdate(changedProps: PropertyValues): boolean {
Expand All @@ -57,13 +64,13 @@ export default class RoomCard extends LitElement {
this.info_entities = this.config.info_entities?.map(entity => mapStateObject(entity, hass, this.config)) ?? [];

this.entities = this.config.entities?.map(entity => mapStateObject(entity, hass, this.config)) ?? [];
this.rows =
this.rows =
this.config.rows?.map((row) => {
const rowEntities = row.entities?.map(entity => mapStateObject(entity, hass, this.config));
return { entities: rowEntities, hide_if: row.hide_if, content_alignment: row.content_alignment };
}) ?? [];

this._refCards = this.config.cards?.map(card => createCardElement(card, hass));
this._refCards = this.config.cards?.map((card) => this.createCardElement(card, hass));

this.config.hass = hass;
}
Expand Down Expand Up @@ -103,4 +110,27 @@ export default class RoomCard extends LitElement {

return numberOfCards + numberOfRows + (this.config.entities ? this.config.entities.length > 0 ? 1 : 0 : 0) + mainSize;
}
}

createCardElement(config: RoomCardLovelaceCardConfig, hass: HomeAssistant) {
if (
hideIfCard(config, hass) ||
(config.show_states && !config.show_states.includes(hass.states[config.entity].state))
) {
return;
}

let element: LovelaceCard;

if (this._helpers) {
element = this._helpers.createCardElement(config);
} else {
element = createThing(config);
}

element.hass = hass;
element.style.boxShadow = 'none';
element.style.borderRadius = '0';

return element;
}
}
38 changes: 8 additions & 30 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { HomeAssistant, createThing } from 'custom-card-helpers';
import { HomeAssistant } from 'custom-card-helpers';
import { html, PropertyValues } from 'lit';
import { HassEntity } from 'home-assistant-js-websocket';
import { UNAVAILABLE_STATES } from './lib/constants';
import { HomeAssistantEntity, RoomCardConfig, RoomCardEntity, EntityCondition, RoomCardLovelaceCardConfig, RoomCardRow, RoomCardIcon, HideIfConfig } from './types/room-card-types';
import { mapTemplate } from './template';
import { hideIfCard } from './hide';

export const isObject = (obj: unknown) : boolean => typeof obj === 'object' && !Array.isArray(obj) && !!obj;

Expand Down Expand Up @@ -36,11 +35,11 @@ export const getConditionEntities = (entities?: RoomCardEntity[]) : EntityCondit
entities?.forEach(entity => {
const iconConditionsWithEntity = (entity?.icon as RoomCardIcon)?.conditions?.filter(x => x.entity !== undefined);
if(iconConditionsWithEntity) {
conditions = conditions.concat(iconConditionsWithEntity);
conditions = conditions.concat(iconConditionsWithEntity);
}
const hideConditionsWithEntity = (entity?.hide_if as HideIfConfig)?.conditions?.filter(x => x.entity !== undefined);
if(hideConditionsWithEntity) {
conditions = conditions.concat(hideConditionsWithEntity);
conditions = conditions.concat(hideConditionsWithEntity);
}
});

Expand Down Expand Up @@ -73,7 +72,7 @@ export const hasConfigOrEntitiesChanged = (node: RoomCardConfig, changedProps: P
return false;
};

export const checkConditionalValue = (item: EntityCondition, checkValue: unknown) => {
export const checkConditionalValue = (item: EntityCondition, checkValue: unknown) => {
const itemValue = typeof item.value === 'boolean' ? String(item.value) : item.value;
if(item.condition == 'equals' && checkValue == itemValue) {
return true;
Expand All @@ -97,27 +96,6 @@ export const mapStateObject = (entity: RoomCardEntity | string, hass: HomeAssist
return { ...conf, stateObj: hass.states[conf.entity] };
}

export const createCardElement = (cardConfig: RoomCardLovelaceCardConfig, hass: HomeAssistant) => {
if (hideIfCard(cardConfig, hass) || cardConfig.show_states && !cardConfig.show_states.includes(hass.states[cardConfig.entity].state)) {
return;
}

let tag = cardConfig.type;
if (tag.startsWith('divider')) {
tag = `hui-divider-row`;
} else if (tag.startsWith('custom:')) {
tag = tag.substr('custom:'.length);
} else {
tag = `hui-${tag}-card`;
}

const element = createThing(cardConfig);
element.hass = hass;
element.style.boxShadow = 'none';
element.style.borderRadius = '0';
return element;
}

// eslint-disable-next-line @typescript-eslint/ban-types
export const evalTemplate = (hass: HomeAssistant | undefined, state: HassEntity, func: string): Function => {
/* eslint no-new-func: 0 */
Expand All @@ -131,10 +109,10 @@ export const evalTemplate = (hass: HomeAssistant | undefined, state: HassEntity,
html,
);
} catch (e) {
const funcTrimmed = func.length <= 100 ? func.trim() : `${func.trim().substring(0, 98)}...`;
e.message = `${e.name}: ${e.message} in '${funcTrimmed}'`;
e.name = 'RoomCardJSTemplateError';
throw e;
const funcTrimmed = func.length <= 100 ? func.trim() : `${func.trim().substring(0, 98)}...`;
e.message = `${e.name}: ${e.message} in '${funcTrimmed}'`;
e.name = 'RoomCardJSTemplateError';
throw e;
}
}

Expand Down
62 changes: 0 additions & 62 deletions tests/util/createCardElement.test.ts

This file was deleted.

0 comments on commit 6e9bb2a

Please sign in to comment.