Skip to content

Commit

Permalink
Revert "feature: support jinja2 template in entityId"
Browse files Browse the repository at this point in the history
This reverts commit 4611ea1.
  • Loading branch information
punxaphil committed Oct 2, 2023
1 parent 4611ea1 commit 88c3223
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 53 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ sections: # see explanation further up
- player
widthPercentage: 75 # default is 100. Use this to change the width of the card.
heightPercentage: 75 # default is 100. Use this to change the height of the card.
entityId: media_player.sonos_bedroom # Forces this player to be the selected one on loading the card (overrides url param etc). Also supports Jinja2 template.
entityId: media_player.sonos_bedroom # Forces this player to be the selected one on loading the card (overrides url param etc)
entityNameRegexToReplace: 'SONOS ' # Regex pattern to replace parts of the entity names
entityNameReplacement: ''
entities: # Entities are automatically discovered if you don't supply this setting
Expand Down
30 changes: 7 additions & 23 deletions src/card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import {
import { when } from 'lit/directives/when.js';
import { styleMap } from 'lit-html/directives/style-map.js';
import { getHeight, getWidth } from './utils/utils';
import HassService from './services/hass-service';
import { until } from 'lit-html/directives/until.js';

const { GROUPING, GROUPS, MEDIA_BROWSER, PLAYER, VOLUMES } = Section;
const TITLE_HEIGHT = 2;
Expand All @@ -33,59 +31,45 @@ export class Card extends LitElement {
@state() cancelLoader!: boolean;
@state() activePlayerId!: string;
render() {
this.createStore();
let height = getHeight(this.config);
const sections = this.config.sections;
const showFooter = !sections || sections.length > 1;
const contentHeight = showFooter ? height - FOOTER_HEIGHT : height;
const title = this.config.title;
height = title ? height + TITLE_HEIGHT : height;
return html` ${until(
this.createStore().then(() => this.renderWithStore(height, title, contentHeight, showFooter)),
html``,
)}`;
}

private renderWithStore(height: number, title: string | undefined, contentHeight: number, showFooter: boolean) {
return html`
<ha-card style="${this.haCardStyle(height)}">
<div class="loader" ?hidden="${!this.showLoader}">
<ha-circular-progress active="" progress="0"></ha-circular-progress>
</div>
${title ? html` <div class="title">${title}</div>` : html``}
${title ? html`<div class="title">${title}</div>` : html``}
<div class="content" style="${this.contentStyle(contentHeight)}">
${choose(this.section, [
[PLAYER, () => html` <sonos-player .store=${this.store}></sonos-player>`],
[GROUPS, () => html` <sonos-groups .store=${this.store}></sonos-groups>`],
[GROUPING, () => html` <sonos-grouping .store=${this.store}></sonos-grouping>`],
[GROUPING, () => html`<sonos-grouping .store=${this.store}></sonos-grouping>`],
[MEDIA_BROWSER, () => html` <sonos-media-browser .store=${this.store}></sonos-media-browser>`],
[VOLUMES, () => html` <sonos-volumes .store=${this.store}></sonos-volumes>`],
])}
</div>
${when(
showFooter,
() =>
html` <sonos-footer style=${this.footerStyle()} .config="${this.config}" .section="${this.section}">
html`<sonos-footer style=${this.footerStyle()} .config="${this.config}" .section="${this.section}">
</sonos-footer>`,
)}
</ha-card>
`;
}

private async createStore() {
let entityId = this.config.entityId;
const hassService = new HassService(this.hass, this.section);
if (entityId && entityId.indexOf('{{') > -1) {
entityId = await hassService.renderTemplate<string>(entityId);
}
this.config = { ...this.config, entityId };
private createStore() {
if (this.activePlayerId) {
this.store = new Store(this.hass, this.config, hassService, this.activePlayerId);
this.store = new Store(this.hass, this.config, this.activePlayerId);
} else {
this.store = new Store(this.hass, this.config, hassService);
this.store = new Store(this.hass, this.config);
this.activePlayerId = this.store.activePlayer.id;
}
}

getCardSize() {
return 3;
}
Expand Down
4 changes: 2 additions & 2 deletions src/model/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default class Store {
public allMediaPlayers: MediaPlayer[];
public predefinedGroups: PredefinedGroup[];

constructor(hass: HomeAssistant, config: CardConfig, hassService?: HassService, activePlayerId?: string) {
constructor(hass: HomeAssistant, config: CardConfig, activePlayerId?: string) {
this.hass = hass;
this.config = config;
const mediaPlayerHassEntities = this.getMediaPlayerHassEntities(this.hass);
Expand All @@ -37,7 +37,7 @@ export default class Store {
.sort((a, b) => a.name.localeCompare(b.name));
this.activePlayer = this.determineActivePlayer(activePlayerId);
const section = this.config.sections?.[0];
this.hassService = hassService ?? new HassService(this.hass, section);
this.hassService = new HassService(this.hass, section);
this.mediaControlService = new MediaControlService(this.hassService);
this.mediaBrowseService = new MediaBrowseService(this.hassService);
this.predefinedGroups = this.createPredefinedGroups();
Expand Down
35 changes: 11 additions & 24 deletions src/services/hass-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { HassEntity } from 'home-assistant-js-websocket';
export default class HassService {
private readonly hass: HomeAssistant;
private readonly sectionOnCreate?: Section;
private templateCache: { [key: string]: unknown } = {};

constructor(hass: HomeAssistant, section?: Section) {
this.hass = hass;
Expand Down Expand Up @@ -46,34 +45,22 @@ export default class HassService {
}

async getRelatedSwitchEntities(player: MediaPlayer) {
return (await this.renderTemplate<string[]>("{{ device_entities(device_id('" + player.id + "')) }}"))
.filter((item: string) => item.indexOf('switch') > -1)
.map((item) => this.hass.states[item]);
}

async renderTemplate<T>(template: string) {
const cachedRender = this.templateCache[template] as T;
if (cachedRender) {
return cachedRender;
}
const result = await new Promise<T>(async (resolve, reject) => {
return new Promise<HassEntity[]>(async (resolve, reject) => {
const subscribeMessage = {
type: 'render_template',
template: "{{ device_entities(device_id('" + player.id + "')) }}",
};
try {
const unsubscribe = await this.hass.connection.subscribeMessage<TemplateResult<T>>(
(response) => {
unsubscribe();
resolve(response.result);
},
{
type: 'render_template',
template,
},
);
const unsubscribe = await this.hass.connection.subscribeMessage<TemplateResult>((response) => {
unsubscribe();
resolve(
response.result.filter((item: string) => item.indexOf('switch') > -1).map((item) => this.hass.states[item]),
);
}, subscribeMessage);
} catch (e) {
reject(e);
}
});
this.templateCache[template] = result;
return result;
}

async toggle(entity: HassEntity) {
Expand Down
5 changes: 2 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export enum Section {
export type ConfigPredefinedGroupPlayer = PredefinedGroupPlayer<string>;
export type ConfigPredefinedGroup = PredefinedGroup<string | ConfigPredefinedGroupPlayer>;
export interface CardConfig extends LovelaceCardConfig {
entityId?: string;
sections?: Section[];
showVolumeUpAndDownButtons: boolean;
entities?: string[];
Expand Down Expand Up @@ -92,6 +91,6 @@ export interface PredefinedGroupPlayer<T = MediaPlayer> {
player: T;
volume?: number;
}
export interface TemplateResult<T> {
result: T;
export interface TemplateResult {
result: string[];
}

0 comments on commit 88c3223

Please sign in to comment.