Hallo an alle,
ich wollte hier mal meine Lösung zum Zappen mit Enigma2 Receivern vorstellen.
Es ist sicherlich nicht das schönste Script aber es tut was es soll 
Ich war ewig auf der Suche nach einer Lösung und habe dann mittels MariaDB und JavaScript einen gangbaren Weg für mich gefunden.
Das Script extrahiert per http die Bouquet- und Channellist als XML, fügt diese per SQL in eine Datenbank ein und erstellt automatisch ein Smart-Gerät für jeden Kanal.
Zum Zappen habe ich ein Script geschrieben, dass per SQL-Abfrage die Ref-ID des senders aus der Datenbank ausliest und diese im E2-Adapter an den Datenpunkt ZAP übergibt.
Vorraussetzungen zum Betrieb:
- MariaDB mit Nutzer und Rechten
- cURL
- SQL-Adapter
- Enigma2-Adapter
Hier das Script zum Erstellen der Kanäle:
//Datenbankname
var datenbank = "iobroker";
//SQL-Adapter-Instanz
var sqlInstanz = "sql.0";
//IP des Receivers
var box = "xxx.xxx.xxx.xxx";
//Bouquet-Namen
var bouquet = new Array("Lenny","Chefin","Kind");
//Identifier für Bouquets
var ident = new Array("","PL","");
//Anzahl Kanäle
var idMax = 0;
//Timeouts
function Sleep (milliseconds) {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}
//Instanzen müssen hier angepasst werden
async function ChanUpdate () {
//Script für ZAP ausschalten
setState("javascript.0.scriptEnabled.Zappen", false);
console.log("Zap OFF");
//Lösche Tabellen
sendTo(sqlInstanz, 'query', 'DROP TABLE ' + datenbank + '.bouquet');
await Sleep (10);
sendTo(sqlInstanz, 'query', 'DROP TABLE ' + datenbank + '.tv');
await Sleep (10);
console.log("Tables gelöscht");
//Lösche alte Kanäle
$('javascript.0.channels.*').each(function (id) {
deleteState(id);
});
await Sleep (10);
console.log("Channels in iobroker gelöscht");
//Erstelle leere Tabellen
sendTo(sqlInstanz, 'query', 'CREATE TABLE ' + datenbank + '.bouquet (id int NOT NULL AUTO_INCREMENT, e2servicereference varchar(255), e2servicename varchar(255), PRIMARY KEY (id));');
await Sleep (10)
sendTo(sqlInstanz, 'query', 'CREATE TABLE ' + datenbank + '.tv (e2servicereference varchar(255), e2servicename varchar(255), bouquet varchar(255));');
await Sleep (10);
console.log("Tables erstellt");
//Lese Bouquets aus
exec('curl http://' + box + '/web/getservices > /home/iobroker/services.xml');
await Sleep (1000);
console.log("Bouquets gelesen");
//Schreibe Bouquets in Datenbank
sendTo(sqlInstanz, 'query', "LOAD XML LOCAL INFILE '/home/iobroker/services.xml' INTO TABLE " + datenbank + ".bouquet ROWS IDENTIFIED BY '<e2service>';");
await Sleep (1000)
console.log("Bouquets geschrieben");
//Manipuliere Bouquet-Name
sendTo(sqlInstanz, 'query', "UPDATE " + datenbank + ".bouquet SET e2servicereference = REPLACE(e2servicereference, ' ', '%20') WHERE INSTR(e2servicereference, ' ') > 0");
await Sleep (1000);
sendTo(sqlInstanz, 'query', "UPDATE " + datenbank + ".bouquet SET e2servicereference = REPLACE(e2servicereference, '" + '"' + "', '%22') WHERE INSTR(e2servicereference, '" + '"' + "') > 0");
await Sleep (1000);
console.log("Bouquets manipuliert");
//Erstelle Channel-XML für jedes Bouquet
for (let i = 0; i < bouquet.length; i++) {
console.log(bouquet[i]);
sendTo(sqlInstanz, 'query', 'SELECT e2servicereference as channel FROM ' + datenbank + '.bouquet WHERE e2servicename LIKE "' + bouquet[i] + '";', function (result) {
//Extrahiere services XML
exec('curl http://' + box + '/web/getservices?sRef='+ result.result[0].channel + ' > /home/iobroker/services' + bouquet[i] + '.xml');
});
await Sleep (1000);
console.log(bouquet[i] + " xml geschrieben");
//Importiere xml
sendTo(sqlInstanz, 'query', "LOAD XML LOCAL INFILE '/home/iobroker/services" + bouquet[i] + ".xml' INTO TABLE " + datenbank + ".tv ROWS IDENTIFIED BY '<e2service>' SET bouquet = '" + ident[i] + "';");
await Sleep (1000);
console.log(bouquet[i] + " in DB geschrieben");
//Manipuliere Kanalnamen
sendTo(sqlInstanz, 'query', "UPDATE " + datenbank + ".tv SET e2servicename = REPLACE(e2servicename, '.', ' ') WHERE INSTR(e2servicename, '.') > 0");
await Sleep (100);
sendTo(sqlInstanz, 'query', "UPDATE " + datenbank + ".tv SET e2servicename = REPLACE(e2servicename, 'III', '3') WHERE INSTR(e2servicename, 'III') > 0");
await Sleep (100)
sendTo(sqlInstanz, 'query', "UPDATE " + datenbank + ".tv SET e2servicename = REPLACE(e2servicename, 'II', '2') WHERE INSTR(e2servicename, 'II') > 0");
await Sleep (100)
console.log(bouquet[i] + " Channels manipuliert");
}
//Füge index hinzu
sendTo(sqlInstanz, 'query', "ALTER TABLE " + datenbank + ".tv ADD id INT AUTO_INCREMENT PRIMARY KEY;");
await Sleep (100);
sendTo(sqlInstanz, 'query', "UPDATE " + datenbank + ".tv SET e2servicename=CONCAT(e2servicename, ' ', bouquet);");
await Sleep (100);
console.log("Index geschrieben");
//Erstelle Kanäle
sendTo(sqlInstanz, 'query', 'SELECT COUNT(*) as idMax FROM ' + datenbank + '.tv', function (result) {
idMax = result.result[0].idMax;
console.log (idMax);
});
await Sleep (100);
console.log (idMax);
for (let j = 1; j < idMax; j++) {
sendTo(sqlInstanz, 'query', 'SELECT e2servicename as channel FROM ' + datenbank + '.tv WHERE id = ' + j, function (result) {
var kanal = result.result[0].channel;
console.log(kanal);
createState("javascript.0.channels." + kanal, false, {
read: true,
write: true,
desc: kanal,
type: "boolean",
def: false,
role: "switch",
smartName: { 'de': kanal},
});
});
await Sleep (10);
};
console.log("Channels in iobroker geschrieben");
//Script für ZAP einschalten
setState("javascript.0.scriptEnabled.Zappen", true);
console.log("ZAP on");
}
ChanUpdate();
Im Script müssen die Variablen angepasst werden.
Das erste Array für Bouquet-Namen muss ausgefüllt werden!
Da müssen einfach eure Bouquet-Namen rein.
Das Identifier-Array muss um die Anzahl euer Bouquet-Einträge erweitert werden. Dieses Array dient dazu um Kanäle eindeutig zu identifizieren.
Mein Frau ist gebürtige Polin und deswegen haben wir auch polnische Sender. Da Sender wie z.B. TNT auch in anderen Ländern verfügbar sind, gibt es den Identifier. Das Gerät heißt dann z.B. bei mir "TNT Film HD" und bei meiner Frau "TNT Film HD PL".
Hier mein Zap-Script:
//Datenbankname
var datenbank = "iobroker";
//Adapter-Instanz
var sqlInstanz = "sql.0";
//Trigger auf alle Objekte im Ordner Channel
on({id: new RegExp("javascript\.0\.channels\.[a-zA-Z0-9]+"), change:"any"}, function (obj) {
var value = obj.state.val;
var oldValue = obj.oldState.val;
//Name des geänderten Objektes auslesen
var str = obj.common.name;
//Name in Array einlesen
var channel = str.split('.');
//Referenz-ID des gewählten Senders suchen und umschalten
sendTo(sqlInstanz, 'query', 'SELECT e2servicereference as channel FROM ' + datenbank + '.tv WHERE e2servicename = "' + channel[3] + '"', function (result) {
setState("enigma2.0.command.ZAP", result.result[0].channel);
break;
});
});
Ich bin nicht so der Erklär-Bär, aber hoffe dass ich damit einigen helfen konnte.
Fragen einfach hier rein 