Code:
// --- KONFIGURATION GIGABLUE ENIGMA2 BOX---
const BOX_IP = '192.168.178.37'; // IP deiner Enigma2 Box
const TARGET_JSON_DP = '0_userdata.0.enigma2.epg_json';
const TARGET_HTML_DP = '0_userdata.0.enigma2.epg_html';
// ---------------------
const axios = require('axios');
// Datenpunkte erstellen, falls sie fehlen
await createStateAsync(TARGET_JSON_DP, { name: 'Enigma2 EPG JSON', type: 'string', role: 'json', read: true, write: false });
await createStateAsync(TARGET_HTML_DP, { name: 'Enigma2 EPG HTML für VIS', type: 'string', role: 'html', read: true, write: false });
// Holt vollautomatisch die exakte ID des ersten TV-Bouquets
async function fetchValidBouquetRef() {
try {
const response = await axios.get(`http://${BOX_IP}/api/getservices`, { timeout: 3000 });
if (response && response.data && response.data.services) {
const services = response.data.services;
// Fall 1: API liefert ein direktes Array
if (Array.isArray(services) && services.length > 0) {
return services[0].servicereference;
}
// Fall 2: API liefert ein verschachteltes Objekt
if (services.servicereference) {
return services.servicereference;
}
}
} catch (e) {
log(`Enigma2: Fehler beim automatischen Bouquet-Abruf: ${e.message}`, 'warn');
}
return null;
}
function buildHtmlTable(epgData) {
if (!epgData || !epgData.events || !Array.isArray(epgData.events) || epgData.events.length === 0) {
return '<p style="color: #ff5252; padding: 10px;">Keine EPG-Daten empfangen. Bitte Bouquet-Einstellung prüfen.</p>';
}
let html = `
<style>
.e2-epg-table { width: 100%; border-collapse: collapse; font-family: sans-serif; font-size: 14px; color: #ffffff; }
.e2-epg-table tr { border-bottom: 1px solid #444444; }
.e2-epg-table tr:nth-child(even) { background-color: rgba(32,32,32,0.5); }
.e2-epg-table td { padding: 10px 8px; vertical-align: top; }
.e2-ch-name { font-weight: bold; color: #3498db; width: 33%; }
.e2-time { color: #f1c40f; font-weight: bold; width: 33%; white-space: nowrap; }
.e2-title { font-weight: bold; color: #ffffff; margin-bottom: 3px; }
.e2-desc { color: #aaaaaa; font-size: 12px; line-height: 1.3; }
</style>
<table class="e2-epg-table">
`;
epgData.events.forEach(event => {
if (!event.sname || !event.event_title) return;
const startTime = new Date(event.event_start * 1000);
const timeString = startTime.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }) + ' Uhr';
html += `
<tr>
<td class="e2-ch-name">${event.sname}</td>
<td class="e2-time">${timeString}</td>
<td>
<div class="e2-title">${event.event_title}</div>
<div class="e2-desc">${event.event_description || ''}</div>
</td>
</tr>
`;
});
html += '</table>';
return html;
}
async function updateEPG() {
try {
// 1. Automatisch die korrekte, vom OpenWebif akzeptierte ID ermitteln
const verifiedBref = await fetchValidBouquetRef();
if (!verifiedBref) {
log('Enigma2 EPG abgebrochen: Es konnte keine gültige Bouquet-Referenz von der Box gelesen werden.', 'error');
return;
}
// 2. Abfrage mit dem vom OpenWebif exakt geforderten Parameter 'bRef'
const url = `http://${BOX_IP}/api/epgnow?bRef=${encodeURIComponent(verifiedBref)}`;
const response = await axios.get(url, { timeout: 5000 });
if (response && response.status === 200 && response.data) {
const data = response.data;
if (data.result === false) {
log(`Enigma2 meldet Fehler im Payload: ${data.message || 'Unbekannt'}`, 'warn');
return;
}
// 1. JSON speichern
await setStateAsync(TARGET_JSON_DP, JSON.stringify(data), true);
// 2. HTML generieren und speichern
const htmlTable = buildHtmlTable(data);
await setStateAsync(TARGET_HTML_DP, htmlTable, true);
log('Enigma2 EPG erfolgreich aktualisiert.', 'info');
} else {
const status = response ? response.status : 'Keine Antwort';
log(`Enigma2 HTTP-Fehler: Status ${status}`, 'warn');
}
} catch (error) {
log(`Enigma2 EPG-Abruf fehlgeschlagen: ${error.message}`, 'warn');
}
}
// Trigger: Alle 15 Minuten
schedule('*/15 * * * *', updateEPG);
// Sofortstart beim Speichern
updateEPG();
Anzeige in VIS nix