- Mai întâi instalează integrarea, EPG:
2. Creează un dashboard pentru această afișare sau o secțiune separată într-un dashboard.
3. Pentru ca HA nu permite afisarea unui numar mai mare de 200 și ceva de mii de caractere, am redus descrierea continutului programelor si am impartit cardul în două, tot pentru a evita aglomerarea a peste 200.000 de caractere.
Creează cele două carduri manual și introdu codurile yaml:
type: markdown
content: >
<div style="overflow-x: auto; white-space: nowrap; width: 100%;"> <table
style="border-collapse: separate; border-spacing: 0; width: auto;">
<thead>
<tr style="background-color: #2c3e50; color: white;">
<th style="padding: 10px; border: 1px solid #444; position: sticky; left: 0; background: #2c3e50; z-index: 10; min-width: 120px;">Canal</th>
<th style="padding: 10px; border: 1px solid #444; min-width: 200px; background: #2c3e50;">Acum</th>
<th style="padding: 10px; border: 1px solid #444; min-width: 200px; background: #2c3e50;">Urmează</th>
<th style="padding: 10px; border: 1px solid #444; min-width: 200px; background: #2c3e50;">+1</th>
<th style="padding: 10px; border: 1px solid #444; min-width: 200px; background: #2c3e50;">+2</th>
<th style="padding: 10px; border: 1px solid #444; min-width: 200px; background: #2c3e50;">+3</th>
<th style="padding: 10px; border: 1px solid #444; min-width: 200px; background: #2c3e50;">+4</th>
</tr>
</thead>
<tbody>
{%- set senzori = [
'sensor.crime_investigat', 'sensor.id_investigation_discovery', 'sensor.national_geographic',
'sensor.discovery_chan', 'sensor.cinemara', 'sensor.epic_dr', 'sensor.hbo', 'sensor.hbo_2',
'sensor.hbo_3', 'sensor.cinemax', 'sensor.cinemax_2', 'sensor.film_now', 'sensor.film_cafe',
'sensor.pro_cinema', 'sensor.warner_tv'
] -%}
{%- set now_m = now().hour * 60 + now().minute -%}
{%- for s in senzori -%}
{%- if states[s] is defined -%}
{%- set ns = namespace(all_shows=[], display_list=[]) -%}
{%- set today_data = state_attr(s, 'today') -%}
{%- if today_data -%}
{%- for key, val in today_data.items() -%}
{%- set k_str = key | string -%}
{%- set parts = k_str.split(':') -%}
{%- if parts|length == 2 -%}
{%- set start_min = parts[0]|int * 60 + parts[1]|int -%}
{%- if val is mapping -%}
{%- set raw_title = val.title | default('Fără Titlu') -%}
{%- set raw_desc = val.desc | default('Descriere indisponibilă.') -%}
{%- else -%}
{%- set raw_title = val | string -%}
{%- set raw_desc = 'Descriere indisponibilă.' -%}
{%- endif -%}
{%- set titlu = raw_title if raw_title | trim != "" else "Program Indisponibil" -%}
{%- set new_item = {'title': titlu, 'description': raw_desc, 'start': k_str, 'sort_index': start_min} -%}
{%- set ns.all_shows = ns.all_shows + [new_item] -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
{%- set sorted = ns.all_shows | sort(attribute='sort_index') -%}
{%- set past_shows = sorted | selectattr('sort_index', '<=', now_m) | list -%}
{%- if past_shows | length > 0 -%}
{%- set current_show = past_shows | last -%}
{%- set ns.display_list = ns.display_list + [dict(current_show, **{'is_current': true})] -%}
{%- else -%}
{%- set ns.display_list = ns.display_list + [{'title': 'Fără date', 'description': '', 'start': '--:--', 'is_current': true}] -%}
{%- endif -%}
{%- set future_shows = sorted | selectattr('sort_index', '>', now_m) | list -%}
{%- for show in future_shows[:5] -%}
{%- set ns.display_list = ns.display_list + [dict(show, **{'is_current': false})] -%}
{%- endfor -%}
<tr style="border-bottom: 1px solid #333;">
<td style="padding: 10px; font-weight: bold; position: sticky; left: 0; background: var(--card-background-color, #1c1c1c); border-right: 2px solid var(--primary-color); z-index: 5; height: 60px;">
{{ state_attr(s, 'friendly_name') | replace('EPG ', '') | default(s) }}
</td>
{%- if ns.display_list | length > 0 -%}
{%- for show in ns.display_list -%}
{%- if show.is_current -%}
<td style="padding: 10px; min-width: 200px; border-right: 1px solid #444; background: rgba(231, 76, 60, 0.1); vertical-align: top;">
<span style="color: #e74c3c; font-weight: bold;">● {{ show.start }}</span><br>
<details><summary style="cursor: pointer; outline: none;"><b>{{ show.title }}</b></summary>
<div style="font-size: 0.9em; margin-top: 5px; color: #fff; white-space: normal; background: rgba(0,0,0,0.3); padding: 5px; border-radius: 4px;">{{ show.description | truncate(60, True) }}</div></details>
</td>
{%- else -%}
<td style="padding: 10px; min-width: 200px; border-right: 1px solid #333; vertical-align: top;">
<span style="color: #3498db; font-weight: bold;">{{ show.start }}</span><br>
<details><summary style="cursor: pointer; outline: none; color: #ccc;">{{ show.title }}</summary>
<div style="font-size: 0.9em; margin-top: 5px; color: #aaa; white-space: normal; background: rgba(0,0,0,0.3); padding: 5px; border-radius: 4px;">{{ show.description | truncate(60, True) }}</div></details>
</td>
{%- endif -%}
{%- endfor -%}
{%- set slots_needed = 6 - ns.display_list|length -%}
{%- for i in range(slots_needed) -%}
<td style="padding: 10px; min-width: 200px; border-right: 1px solid #333; background: rgba(0,0,0,0.1);"></td>
{%- endfor -%}
{%- else -%}
<td colspan="6" style="padding: 10px; min-width: 200px; color: #aaa; font-style: italic;">Fără date</td>
{%- endif -%}
</tr>
{%- endif -%}
{%- endfor -%}
</tbody>
</table> </div>
grid_options:
columns: 48
rows: auto
type: markdown
content: >
<div style="overflow-x: auto; white-space: nowrap; width: 100%;"> <table
style="border-collapse: separate; border-spacing: 0; width: auto;">
<tbody>
{%- set senzori = [
'sensor.axn', 'sensor.axn_bl', 'sensor.axn_wh',
'sensor.axn_s', 'sensor.pro_tv', 'sensor.antena_1', 'sensor.tvr_1', 'sensor.tvr_i',
'sensor.tv1', 'sensor.digi_24', 'sensor.antena_3_cnn', 'sensor.euronews_romania',
'sensor.cnn', 'sensor.bbc_news', 'sensor.eurosport_1', 'sensor.eurosport_2'
] -%}
{%- set now_m = now().hour * 60 + now().minute -%}
{%- for s in senzori -%}
{%- if states[s] is defined -%}
{%- set ns = namespace(all_shows=[], display_list=[]) -%}
{%- set today_data = state_attr(s, 'today') -%}
{%- if today_data -%}
{%- for key, val in today_data.items() -%}
{%- set k_str = key | string -%}
{%- set parts = k_str.split(':') -%}
{%- if parts|length == 2 -%}
{%- set start_min = parts[0]|int * 60 + parts[1]|int -%}
{%- if val is mapping -%}
{%- set raw_title = val.title | default('Fără Titlu') -%}
{%- set raw_desc = val.desc | default('Descriere indisponibilă.') -%}
{%- else -%}
{%- set raw_title = val | string -%}
{%- set raw_desc = 'Descriere indisponibilă.' -%}
{%- endif -%}
{%- set titlu = raw_title if raw_title | trim != "" else "Program Indisponibil" -%}
{%- set new_item = {'title': titlu, 'description': raw_desc, 'start': k_str, 'sort_index': start_min} -%}
{%- set ns.all_shows = ns.all_shows + [new_item] -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
{%- set sorted = ns.all_shows | sort(attribute='sort_index') -%}
{%- set past_shows = sorted | selectattr('sort_index', '<=', now_m) | list -%}
{%- if past_shows | length > 0 -%}
{%- set current_show = past_shows | last -%}
{%- set ns.display_list = ns.display_list + [dict(current_show, **{'is_current': true})] -%}
{%- else -%}
{%- set ns.display_list = ns.display_list + [{'title': 'Fără date', 'description': '', 'start': '--:--', 'is_current': true}] -%}
{%- endif -%}
{%- set future_shows = sorted | selectattr('sort_index', '>', now_m) | list -%}
{%- for show in future_shows[:5] -%}
{%- set ns.display_list = ns.display_list + [dict(show, **{'is_current': false})] -%}
{%- endfor -%}
<tr style="border-bottom: 1px solid #333;">
<td style="padding: 10px; font-weight: bold; position: sticky; left: 0; background: var(--card-background-color, #1c1c1c); border-right: 2px solid var(--primary-color); z-index: 5; height: 60px; min-width: 120px;">
{{ state_attr(s, 'friendly_name') | replace('EPG ', '') | default(s) }}
</td>
{%- if ns.display_list | length > 0 -%}
{%- for show in ns.display_list -%}
{%- if show.is_current -%}
<td style="padding: 10px; min-width: 200px; border-right: 1px solid #444; background: rgba(231, 76, 60, 0.1); vertical-align: top;">
<span style="color: #e74c3c; font-weight: bold;">● {{ show.start }}</span><br>
<details><summary style="cursor: pointer; outline: none;"><b>{{ show.title }}</b></summary>
<div style="font-size: 0.9em; margin-top: 5px; color: #fff; white-space: normal; background: rgba(0,0,0,0.3); padding: 5px; border-radius: 4px;">{{ show.description | truncate(60, True) }}</div></details>
</td>
{%- else -%}
<td style="padding: 10px; min-width: 200px; border-right: 1px solid #333; vertical-align: top;">
<span style="color: #3498db; font-weight: bold;">{{ show.start }}</span><br>
<details><summary style="cursor: pointer; outline: none; color: #ccc;">{{ show.title }}</summary>
<div style="font-size: 0.9em; margin-top: 5px; color: #aaa; white-space: normal; background: rgba(0,0,0,0.3); padding: 5px; border-radius: 4px;">{{ show.description | truncate(60, True) }}</div></details>
</td>
{%- endif -%}
{%- endfor -%}
{%- set slots_needed = 6 - ns.display_list|length -%}
{%- for i in range(slots_needed) -%}
<td style="padding: 10px; min-width: 200px; border-right: 1px solid #333; background: rgba(0,0,0,0.1);"></td>
{%- endfor -%}
{%- else -%}
<td colspan="6" style="padding: 10px; min-width: 200px; color: #aaa; font-style: italic;">Fără date</td>
{%- endif -%}
</tr>
{%- endif -%}
{%- endfor -%}
</tbody>
</table> </div>
grid_options:
columns: 48
rows: auto
Ar trebui sa arate cam așa:
