Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. [Vorlage] E2 Kanalliste auslesen und per Alexa umschalten

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    [Vorlage] E2 Kanalliste auslesen und per Alexa umschalten

    This topic has been deleted. Only users with topic management privileges can see it.
    • L
      LennyCole last edited by LennyCole

      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 😉

      Glasfaser 1 Reply Last reply Reply Quote 0
      • Glasfaser
        Glasfaser @LennyCole last edited by Glasfaser

        @LennyCole

        Es funktioniert leider nicht , aber erstmal eine gute Idee !!

        setState habe ich Auskommentiert , sonst wird das Script sofort beim Start beendet

        1.JPG

        Ich denke mal nach dem Einlesen willst du das Script dann ausschalten , aber dann wäre der Wert falsch .

        44444444.JPG
        .
        Mußte das Script mehrmals starten , damit dann die Tabelle erstellt bzw. auch dann die Datenpunkte erzeugt werden , sind auch ein haufen Warn enthalten .

        4.JPG

        .
        Nach dem schalten vom Datenpunkt kommt nur eine Warn und es wird kein Programm geschaltet .

        Hier der Log :

        LOG.txt

        1 Reply Last reply Reply Quote 0
        • L
          LennyCole last edited by LennyCole

          Das Script zum Zappen hat "break" im Code. My fault
          Ich habe noch eine Case-Abfrage drin, welcher echo dot anfragt und damit wird bestimmt welcher Receiver umschaltet.
          Lösche mal das break;

          Zurück zum Problem:
          Es ist möglich, dass du die Zeiten der Timeouts erhöhen musst. Beim ersten Durchlauf müssen auf jeden Fall Fehler auftauchen da die Tables ja nicht existieren. (Da könnte man noch ein Abfangen des Fehlers einbauen).

          Edit:
          Das erste Script heißt Channel-Update bei mir. Wenn du es Zappen genannt hast, dann wird es natürlich beendet. das zweite Script ist Zappen

          Glasfaser 1 Reply Last reply Reply Quote 0
          • Glasfaser
            Glasfaser @LennyCole last edited by Glasfaser

            @LennyCole sagte in [Vorlage] Enigma2 Kanalliste auslesen und Geräte erstellen:

            Lösche mal das break;

            Funktioniert über die Datenpunkte 👍

            Ahh , deshalb " scriptEnabled " habe mich schon gewundern , sollte für das andere Script sein .

            Besser wäre dann scriptEnabled true zu für Zappen setzen wenn alle Datenpunkte erzeugt sind ,weil wenn nichts erzeugt wird setzt er dann Ihn zum Schluss trotzdem auf true .
            War nicht gerade schön das er alle beim erstellen Duchgezappt hat ( habe gerade den Fernseher an ).. da ja auf any gehört wird mit deinem Zapper Script , wo er noch beim erstellen der Datenpunkte war

            Das Script Channel-Update sollte auch lieber dannach ausgeschaltet werden , da es beim Neustart vom System oder wenn Javascript abschmiert dann anschließend dein Programm gestartet wird .

            1 Reply Last reply Reply Quote 0
            • L
              LennyCole last edited by LennyCole

              Dann lass uns das Script perfektionieren mit Hilfe des Forums 🙂

              EDIT:
              Ich schrieb, dass eventuell die Timeouts angepasst werden müssen!
              Bei mir ist Zap aus, dann werden channels gelöscht und neu geschrieben und dann ist Zap wieder an.

              Ich bin leider noch nicht so mit callbacks bei JavaScript involviert um es wirklich asynchron laufen zu lassen. Sollte es bei Dir zappen, dann ist entweder das Script beim Channel-Update nicht aus, oder du musst die Timeouts erhöhen bis keine Fehlermedung mehr zu sehen ist

              1 Reply Last reply Reply Quote 0
              • First post
                Last post

              Support us

              ioBroker
              Community Adapters
              Donate

              689
              Online

              31.9k
              Users

              80.2k
              Topics

              1.3m
              Posts

              2
              5
              396
              Loading More Posts
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes
              Reply
              • Reply as topic
              Log in to reply
              Community
              Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
              The ioBroker Community 2014-2023
              logo