Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed card creation to use lovelace helper #248

Merged
merged 1 commit into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.

Loading