Skip to content
This repository has been archived by the owner on Aug 30, 2024. It is now read-only.

Commit

Permalink
Hiding feature for entity rows (#74)
Browse files Browse the repository at this point in the history
* Hiding feature for entity rows
  • Loading branch information
marcokreeft87 committed Sep 29, 2022
1 parent ec0cf9f commit c033db6
Show file tree
Hide file tree
Showing 13 changed files with 184 additions and 50 deletions.
4 changes: 4 additions & 0 deletions info.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

### Features

{% if version_installed.replace("v", "").replace(".","") | int < 10610 %}
- Added `Hiding feature for entity rows`
{% endif %}

{% if version_installed.replace("v", "").replace(".","") | int < 10601 %}
- Fixed `Formatting not working for entities and row entities`
{% endif %}
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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.06.01",
"version": "1.06.10",
"description": "Show entities in Home Assistant's Lovelace UI",
"keywords": [
"home-assistant",
Expand Down
8 changes: 4 additions & 4 deletions room-card.js

Large diffs are not rendered by default.

Binary file modified room-card.js.gz
Binary file not shown.
21 changes: 15 additions & 6 deletions src/entity.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { secondsToDuration } from './lib/seconds_to_duration';
import { formatNumber } from './lib/format_number';
import { computeStateDisplay, computeStateDomain } from './lib/compute_state_display';
import { checkConditionalValue, evalTemplate, getValue, hideIf, isObject, isUnavailable } from './util';
import { checkConditionalValue, evalTemplate, getValue, hideIfEntity, hideIfRow, isObject, isUnavailable } from './util';
import { ActionConfig, handleClick, HomeAssistant, NumberFormat } from 'custom-card-helpers';
import { HomeAssistantEntity, EntityCondition, RoomCardEntity, RoomCardIcon, RoomCardConfig, EntityStyles } from './types/room-card-types';
import { HomeAssistantEntity, EntityCondition, RoomCardEntity, RoomCardIcon, RoomCardConfig, EntityStyles, RoomCardRow } from './types/room-card-types';
import { html, HTMLTemplateResult, LitElement } from 'lit';
import { LAST_CHANGED, LAST_UPDATED, TIMESTAMP_FORMATS } from './lib/constants';
import { templateStyling } from './template';
Expand Down Expand Up @@ -83,8 +83,9 @@ export const entityStateDisplay = (hass: HomeAssistant, entity: RoomCardEntity)
if (entity.format.startsWith('precision')) {

const precision = parseInt(entity.format.slice(-1), 10);
const localizedValue = hass.locale.number_format === NumberFormat.comma_decimal ? value : value.toString().replaceAll(",",".")
value = formatNumber(localizedValue, hass.locale, {
//console.log(typeof value, value);
//const localizedValue = hass.locale.number_format === NumberFormat.comma_decimal ? value : value.replaceAll(",",".")
value = formatNumber(value, hass.locale, {
minimumFractionDigits: precision,
maximumFractionDigits: precision,
});
Expand Down Expand Up @@ -123,6 +124,14 @@ export const entityStyles = (styles: EntityStyles) =>
.join('')
: '';

export const renderRows = (rows: RoomCardRow[], hass: HomeAssistant, element: LitElement) : HTMLTemplateResult => {
const filteredRows = rows.filter(row => { return !hideIfRow(row, hass); });

return html`${filteredRows.map((row) => {
return renderEntitiesRow(row.entities, hass, element, "width-100");
})}`;
}

export const renderEntitiesRow = (entities: RoomCardEntity[], hass: HomeAssistant, element: LitElement, classes?: string) : HTMLTemplateResult => {
if(entities === undefined) {
return null;
Expand All @@ -132,7 +141,7 @@ export const renderEntitiesRow = (entities: RoomCardEntity[], hass: HomeAssistan
}

export const renderEntity = (entity: RoomCardEntity, hass: HomeAssistant, element: LitElement) : HTMLTemplateResult => {
if (entity.stateObj == undefined || hideIf(entity, hass)) {
if (entity.stateObj == undefined || hideIfEntity(entity, hass)) {
return null;
}

Expand Down Expand Up @@ -258,7 +267,7 @@ export const renderTitle = (entity: RoomCardEntity, config: RoomCardConfig, hass
}

export const renderInfoEntity = (entity: RoomCardEntity, hass: HomeAssistant, element: LitElement) : HTMLTemplateResult => {
if (entity === undefined || !entity.stateObj || hideIf(entity, hass)) {
if (entity === undefined || !entity.stateObj || hideIfEntity(entity, hass)) {
return null;
}

Expand Down
12 changes: 5 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { CSSResult, html, LitElement, PropertyValues, TemplateResult } from 'lit
import { property, customElement } from 'lit/decorators.js';
import { HomeAssistant, LovelaceCard } from 'custom-card-helpers';

import { checkConfig, entityStyles, renderEntitiesRow, renderInfoEntity, renderTitle } from './entity';
import { checkConfig, entityStyles, renderEntitiesRow, renderInfoEntity, renderRows, renderTitle } from './entity';
import { getEntityIds, hasConfigOrEntitiesChanged, mapStateObject, createCardElement } from './util';
import { style } from './styles';
import { HomeAssistantEntity, RoomCardConfig, RoomCardEntity, RoomCardRow } from './types/room-card-types';
Expand Down Expand Up @@ -62,7 +62,7 @@ export default class RoomCard extends LitElement {
this.rows =
this.config.rows?.map((row) => {
const rowEntities = row.entities?.map(entity => mapStateObject(entity, hass, this.config));
return { entities: rowEntities };
return { entities: rowEntities, hide_if: row.hide_if };
}) ?? [];

this._refCards = this.config.cards?.map(card => createCardElement(card, hass));
Expand All @@ -87,11 +87,9 @@ export default class RoomCard extends LitElement {
${this.info_entities.map((entity) => renderInfoEntity(entity, this._hass, this))}
</div>
</div>
${this.rows !== undefined && this.rows.length > 0 ?
this.rows.map((row) => {
return renderEntitiesRow(row.entities, this._hass, this, "width-100");
})
: renderEntitiesRow(this.entities, this._hass, this)}
${this.rows !== undefined && this.rows.length > 0 ?
renderRows(this.rows, this._hass, this) :
renderEntitiesRow(this.entities, this._hass, this)}
${this._refCards}
</ha-card>
`;
Expand Down
3 changes: 2 additions & 1 deletion src/types/room-card-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export interface RoomCardConfig extends LovelaceCardConfig {

export interface RoomCardRow {
entities?: RoomCardEntity[];
hide_if?: HideIfConfig;
}

export interface HomeAssistantEntity extends HassEntity {
Expand All @@ -72,7 +73,7 @@ export interface HideIfConfig {

export interface EntityCondition {
condition?: string;
value?: string | number;
value?: string | number | boolean;
attribute?: string;
entity?: string;
icon?: string;
Expand Down
33 changes: 27 additions & 6 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { HomeAssistant, LovelaceCardConfig, createThing } from 'custom-card-help
import { html, PropertyValues } from 'lit';
import { HassEntity } from 'home-assistant-js-websocket';
import { UNAVAILABLE_STATES } from './lib/constants';
import { HomeAssistantEntity, RoomCardConfig, RoomCardEntity, EntityCondition, HideIfConfig } from './types/room-card-types';
import { HomeAssistantEntity, RoomCardConfig, RoomCardEntity, EntityCondition, HideIfConfig, RoomCardRow } from './types/room-card-types';
import { mapTemplate } from './template';

export const isObject = (obj: unknown) : boolean => typeof obj === 'object' && !Array.isArray(obj) && !!obj;
Expand All @@ -20,7 +20,27 @@ export const getValue = (entity: RoomCardEntity) => {
return entity.attribute ? entity.stateObj.attributes[entity.attribute] : entity.stateObj.state;
}

export const hideIf = (entity: RoomCardEntity, hass: HomeAssistant) => {
export const hideIfRow = (row: RoomCardRow, hass: HomeAssistant) => {
if (row.hide_if === undefined) {
return false;
}

if (<HideIfConfig>row.hide_if)
{
const matchedConditions = (row.hide_if as HideIfConfig).conditions?.filter(item => {

if(item.entity) {
const stateEntity = hass.states[item.entity];

return checkConditionalValue(item, item.attribute ? stateEntity.attributes[item.attribute] : stateEntity.state);
}
});

return matchedConditions?.length > 0;
}
};

export const hideIfEntity = (entity: RoomCardEntity, hass: HomeAssistant) => {
if (hideUnavailable(entity)) {
return true;
}
Expand Down Expand Up @@ -69,16 +89,17 @@ export const hasConfigOrEntitiesChanged = (node: RoomCardConfig, changedProps: P
};

export const checkConditionalValue = (item: EntityCondition, checkValue: unknown) => {
if(item.condition == 'equals' && checkValue == item.value) {
const itemValue = typeof item.value === 'boolean' ? String(item.value) : item.value;
if(item.condition == 'equals' && checkValue == itemValue) {
return true;
}
if(item.condition == 'not_equals' && checkValue != item.value) {
if(item.condition == 'not_equals' && checkValue != itemValue) {
return true;
}
if(item.condition == 'above' && checkValue > item.value) {
if(item.condition == 'above' && checkValue > itemValue) {
return true;
}
if(item.condition == 'below' && checkValue < item.value) {
if(item.condition == 'below' && checkValue < itemValue) {
return true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/entity/renderEntity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ describe('Testing entity file function renderEntity', () => {
${'brightness'} ${'77'} ${'30 %'}
${'duration'} ${'1000'} ${'16:40'}
${'duration-m'} ${'1000'} ${'1'}
${'precision2'} ${'2,2324'} ${'2,23'}
${'precision2'} ${2.2324} ${'2,23'}
${'kilo'} ${'1000'} ${'1'}
${'invert'} ${'1000'} ${'-1.000'}
${'position'} ${'10'} ${'90'}
Expand Down
14 changes: 7 additions & 7 deletions tests/entity/renderValue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ describe('Testing entity file function renderValue', () => {
}),
test.each`
format | state | expected
${'brightness'} ${'77'} ${'30 %'}
${'duration'} ${'1000'} ${'16:40'}
${'duration-m'} ${'1000'} ${'1'}
${'precision2'} ${'2,2324'} ${'2,23'}
${'kilo'} ${'1000'} ${'1'}
${'invert'} ${'1000'} ${'-1.000'}
${'position'} ${'10'} ${'90'}
${'brightness'} ${77} ${'30 %'}
${'duration'} ${1000} ${'16:40'}
${'duration-m'} ${1000} ${'1'}
${'precision2'} ${2.2324} ${'2,23'}
${'kilo'} ${1000} ${'1'}
${'invert'} ${1000} ${'-1.000'}
${'position'} ${10} ${'90'}
${'position'} ${'notanumber'} ${'notanumber'}
`('Passing RoomCardEntity and HomeAssistant should return formatted value', ({format, state, expected}) => {
Expand Down
30 changes: 15 additions & 15 deletions tests/util/hideIf.test.ts → tests/util/hideIfEntity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ import { createMock } from 'ts-auto-mock';
import { HassEntity } from 'home-assistant-js-websocket';
import { UNAVAILABLE } from '../../src/lib/constants';
import { HideIfConfig } from '../../src/types/room-card-types';
import { hideIf } from '../../src/util';
import { hideIfEntity } from '../../src/util';
import { StubHassEntity, StubHomeAssistant, StubRoomCardEntity } from '../testdata';

describe('Testing util file function hideIf', () => {
describe('Testing util file function hideIfEntity', () => {
test('Passing RoomCardEntity with state unavailable and HomeAssistant should return true', () => {
StubRoomCardEntity.hide_unavailable = true;
StubRoomCardEntity.stateObj.state = UNAVAILABLE;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
}),
test('Passing RoomCardEntity with hide_if undefined and HomeAssistant should return false', () => {
StubRoomCardEntity.hide_unavailable = false;
StubRoomCardEntity.hide_if = undefined;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(false);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(false);
}),
test('Passing RoomCardEntity with hide_if and HomeAssistant should return true', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand All @@ -28,7 +28,7 @@ describe('Testing util file function hideIf', () => {
attribute: 'hide_attribute'
}]
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
}),
test('Passing RoomCardEntity with hide_if and HomeAssistant should return false', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand All @@ -42,7 +42,7 @@ describe('Testing util file function hideIf', () => {
attribute: 'hide_attribute'
}]
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(false);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(false);
}),
test('Passing RoomCardEntity with hide_if entity and HomeAssistant should return true', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand All @@ -62,7 +62,7 @@ describe('Testing util file function hideIf', () => {
entity: 'sensor.test_entity'
}]
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
}),
test('Passing RoomCardEntity with hide_if entity and HomeAssistant should return true', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand Down Expand Up @@ -91,7 +91,7 @@ describe('Testing util file function hideIf', () => {
attribute: 'show_state'
}]
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
}),
test('Passing RoomCardEntity with hide_if entity and HomeAssistant should return true', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand All @@ -116,7 +116,7 @@ describe('Testing util file function hideIf', () => {
entity: 'sensor.test_entity'
}]
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
}),
test('Passing RoomCardEntity with hide_if entity and HomeAssistant should return true', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand All @@ -141,7 +141,7 @@ describe('Testing util file function hideIf', () => {
entity: 'sensor.test_entity'
}]
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
}),
test('Passing RoomCardEntity with hide_if entity and HomeAssistant should return true', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand All @@ -161,7 +161,7 @@ describe('Testing util file function hideIf', () => {
entity: 'sensor.test_entity'
}]
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
}),
test('Passing RoomCardEntity with hide_if entity and HomeAssistant should return false', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand All @@ -181,7 +181,7 @@ describe('Testing util file function hideIf', () => {
entity: 'sensor.test_entity'
}]
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(false);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(false);
}),
test('Passing RoomCardEntity with hide_if entity attribute and HomeAssistant should return true', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand All @@ -205,7 +205,7 @@ describe('Testing util file function hideIf', () => {
attribute: 'show_state'
}]
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(true);
}),
test('Passing RoomCardEntity with hide_if entity attribute and HomeAssistant should return false', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand All @@ -229,7 +229,7 @@ describe('Testing util file function hideIf', () => {
attribute: 'show_state'
}]
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(false);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(false);
}),
test('Passing RoomCardEntity with hide_if no conditions and HomeAssistant should return false', () => {
StubRoomCardEntity.hide_unavailable = false;
Expand All @@ -239,6 +239,6 @@ describe('Testing util file function hideIf', () => {
StubRoomCardEntity.hide_if = {
conditions: undefined
} as HideIfConfig;
expect(hideIf(StubRoomCardEntity, StubHomeAssistant)).toBe(false);
expect(hideIfEntity(StubRoomCardEntity, StubHomeAssistant)).toBe(false);
})
})
Loading

0 comments on commit c033db6

Please sign in to comment.