Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. ceng

    NEWS

    • Wir empfehlen: Node.js 22.x

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Profile
    • Following 0
    • Followers 1
    • Topics 8
    • Posts 46
    • Best 2
    • Groups 1

    ceng

    @ceng

    2
    Reputation
    41
    Profile views
    46
    Posts
    1
    Followers
    0
    Following
    Joined Last Online

    ceng Follow
    Starter

    Best posts made by ceng

    • RE: PiHole Adapter ohne Funktion nach Pi-Hole Update auf V6

      @mcm1957 Das wäre super, wenn der alte Adapter neues Leben eingeflösst bekäme, aber ich weiß selbst wie wertvoll Zeit ist...

      Ich habe mir vorübergehend, solange bis jemand mit Ahnung etwas besseres baut, folgendes Script gebaut:

      // 🛠️ Konfiguration
      const userPath = '0_userdata.0.Lokal.Statistics.PiHole';
      const piholeUrl = 'https://MEINPIHOLE';
      const password = 'AUS DER OBERFLÄCHE'; // App-Passwort, nicht GUI-Passwort
      const debug = getState("0_userdata.0.Global.Debug")?.val || false;
      const sillydebug = getState("0_userdata.0.Global.SillyDebug")?.val || false;
      
      // 📊 Datenpunkte mit Beschreibung für den ioBroker
      const datapoints = {
          total: 'Anzahl aller angefragen Domains',
          blocked: 'Zahl der blockierten Domains',
          percent_blocked: 'Blockierte Domains in %',
          unique_domains: 'Eindeutige Domains',
          queries_forwarded: 'Weitergeleitete Anfragen',
          queries_cached: 'Gecachte Anfragen',
      };
      
      // 🔁 Axios einbinden (funktioniert ab js-controller 3.x)
      const axios = require('axios').default;
      
      // Hilfsfunktion für Logs, gibt nur aus wenn SillyDebug=true ist
      function debugLog(msg) {
          const sillyDebug = getState('0_userdata.0.Global.SillyDebug')?.val || false;
          if (sillyDebug) {
              log(msg);
          }
      }
      
      // Hauptfunktion: Authentifizieren, Daten holen und Datenpunkte schreiben
      async function loginAndFetchPiHole() {
          if (debug) console.log('🔐 Authentifiziere Pi-hole…');
      
          try {
              // Login an Pi-hole API, um Session-ID und CSRF-Token zu erhalten
              const authResponse = await axios.post(
                  `${piholeUrl}/api/auth`,
                  { password: password },
                  { httpsAgent: new (require('https').Agent)({ rejectUnauthorized: false }) }
              );
      
              // Session-Daten extrahieren
              const { sid, csrf } = authResponse.data.session || {};
              if (!sid || !csrf) throw new Error('SID oder CSRF fehlt in Antwort');
      
              if (debug) console.log('✅ Authentifizierung erfolgreich');
      
              // Zusammenfassung der Pi-hole Statistiken abfragen
              const summaryResponse = await axios.get(
                  `${piholeUrl}/api/stats/summary`,
                  {
                      headers: {
                          Cookie: `sid=${sid}`,
                          'x-csrf-token': csrf
                      },
                      httpsAgent: new (require('https').Agent)({ rejectUnauthorized: false }),
                  }
              );
      
              const data = summaryResponse.data;
              debugLog('Pi-hole API Rohdaten: ' + JSON.stringify(data));
      
              // Datenpunkte erstellen und mit Werten aus Pi-hole füllen
              for (const key in datapoints) {
                  const dp = `${userPath}.${key}`;
                  await createStateAsync(dp, 0, { name: datapoints[key], type: 'number', read: true, write: false });
      
                  // Wert je Datenpunkt aus der API Antwort zuordnen
                  let value = 0;
                  switch (key) {
                      case 'total': value = data.queries.total; break;
                      case 'blocked': value = data.queries.blocked; break;
                      case 'percent_blocked': value = Math.round(data.queries.percent_blocked); break;
                      case 'unique_domains': value = data.queries.unique_domains; break;
                      case 'queries_forwarded': value = data.queries.forwarded; break;
                      case 'queries_cached': value = data.queries.cached; break;
                      default: value = 666;
                  }
      
                  debugLog(`${dp}: ${value}`);
                  setState(dp, value || 0, true);
              }
      
              if (debug) console.log('✅ Pi-hole Daten aktualisiert');
      
          } catch (err) {
              log('❌ Fehler bei Pi-hole API Zugriff: ' + err.message, 'error');
          }
      }
      
      // ⏰ Intervall: alle 5 Minuten ausführen
      schedule('*/5 * * * *', loginAndFetchPiHole);
      // Direkt beim Start einmal ausführen
      loginAndFetchPiHole();
      
      

      Ich will hier keine Grundsatzdiskussion über Arten der Programmierung oder gar die Adapterentwicklung in Frage stellen. Das Script läuft bei mir, wenn es jemanden hilft, gut, wenn nicht, auch gut.

      CU

      posted in Error/Bug
      ceng
      ceng
    • Grillthermometer WROOM32

      Hallo,
      nachdem jetzt einige Stunden in die Lösung geflossen sind, möchte ich mein Ergebnis dazu teilen.

      Grillthermometer haben die Problematik, dass sie natürlich Temperaturen von weit über 200 Grad Celsius aushalten müssen. Mit den herkömmlichen Senosren DHT, AMS, HTU usw. komme ich da nicht ans Ziel.

      Die Lösung war einfach gefunden.
      ein MAX 6675 mit einer NodeMCU Wroom32
      MAX 6675 bei Amazon
      NodeMCU Wroom32 bei Amazon

      Aber dann ging es los... Welche Einstellungen... Nichts im Netz gefunden. Vll. gibt es dann ja hier in den Kommentaren Hinweise auf andere Hilfeseiten.

      1. PINOUT:

      Pinout WROOM32 zu MAX6675:
      GND -----------> GND
      3V3 ------------> VCC
      D5 ------------> SO
      D19 ------------> CS
      D23 ------------> SCK
      PinoutGrillThermometerMax6675.png

      2. Config
      Kommen wir zu den Einstellungen auf der Tasmota Seite...

      • Öffnen der Tasmota Konsole und Eingabe von SetOption94 1 Vgl. Tasmota Command
        Console 94 1.PNG
      • Template über "Einstellungen\Sonstige Konfiguration" anpassen auf
        {"NAME":"CENG Wroom32FORMAX6675","GPIO":[0,0,320,0,0,2560,1,1,0,1,1,1,0,1,0,2496,0,640,608,2528,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
        Template.PNG
        *Alternativ über "Einstellungen\Vorlage konfigurieren" die Einstellungen vornehmen:
        Vorlage.PNG

      Jetzt sollte der Eintrag für den MAX6675 auf der Hauptseite erscheinen
      Hauptseite.PNG

      Immer noch keine Temperatur Anzeige?
      Ich habe gelernt, dass es ggf. notwendig ist, seine eigene Tasmota Version zu kompilieren. Hierzu guck mal unter Gitpod / Tasmota.

      posted in Off Topic
      ceng
      ceng

    Latest posts made by ceng

    • Template für Shelly Pro 3EM

      Re: [gelöst] Shelly Pro 3EM und TASMOTA

      Es scheint ja zu funktionieren, aber leider finde ich nirgendwo den Link für das Template für den Shelly Pro 3EM.

      Weder Blakadder noch Dr. Google helfen mir weiter. Hat jemand den Shelly mit Tasmota in Betrieb und kann mir das Template zur Verfügung stellen?

      THX
      CENG

      posted in Einbindung von Geräten
      ceng
      ceng
    • RE: PiHole Adapter ohne Funktion nach Pi-Hole Update auf V6

      @mcm1957 Das wäre super, wenn der alte Adapter neues Leben eingeflösst bekäme, aber ich weiß selbst wie wertvoll Zeit ist...

      Ich habe mir vorübergehend, solange bis jemand mit Ahnung etwas besseres baut, folgendes Script gebaut:

      // 🛠️ Konfiguration
      const userPath = '0_userdata.0.Lokal.Statistics.PiHole';
      const piholeUrl = 'https://MEINPIHOLE';
      const password = 'AUS DER OBERFLÄCHE'; // App-Passwort, nicht GUI-Passwort
      const debug = getState("0_userdata.0.Global.Debug")?.val || false;
      const sillydebug = getState("0_userdata.0.Global.SillyDebug")?.val || false;
      
      // 📊 Datenpunkte mit Beschreibung für den ioBroker
      const datapoints = {
          total: 'Anzahl aller angefragen Domains',
          blocked: 'Zahl der blockierten Domains',
          percent_blocked: 'Blockierte Domains in %',
          unique_domains: 'Eindeutige Domains',
          queries_forwarded: 'Weitergeleitete Anfragen',
          queries_cached: 'Gecachte Anfragen',
      };
      
      // 🔁 Axios einbinden (funktioniert ab js-controller 3.x)
      const axios = require('axios').default;
      
      // Hilfsfunktion für Logs, gibt nur aus wenn SillyDebug=true ist
      function debugLog(msg) {
          const sillyDebug = getState('0_userdata.0.Global.SillyDebug')?.val || false;
          if (sillyDebug) {
              log(msg);
          }
      }
      
      // Hauptfunktion: Authentifizieren, Daten holen und Datenpunkte schreiben
      async function loginAndFetchPiHole() {
          if (debug) console.log('🔐 Authentifiziere Pi-hole…');
      
          try {
              // Login an Pi-hole API, um Session-ID und CSRF-Token zu erhalten
              const authResponse = await axios.post(
                  `${piholeUrl}/api/auth`,
                  { password: password },
                  { httpsAgent: new (require('https').Agent)({ rejectUnauthorized: false }) }
              );
      
              // Session-Daten extrahieren
              const { sid, csrf } = authResponse.data.session || {};
              if (!sid || !csrf) throw new Error('SID oder CSRF fehlt in Antwort');
      
              if (debug) console.log('✅ Authentifizierung erfolgreich');
      
              // Zusammenfassung der Pi-hole Statistiken abfragen
              const summaryResponse = await axios.get(
                  `${piholeUrl}/api/stats/summary`,
                  {
                      headers: {
                          Cookie: `sid=${sid}`,
                          'x-csrf-token': csrf
                      },
                      httpsAgent: new (require('https').Agent)({ rejectUnauthorized: false }),
                  }
              );
      
              const data = summaryResponse.data;
              debugLog('Pi-hole API Rohdaten: ' + JSON.stringify(data));
      
              // Datenpunkte erstellen und mit Werten aus Pi-hole füllen
              for (const key in datapoints) {
                  const dp = `${userPath}.${key}`;
                  await createStateAsync(dp, 0, { name: datapoints[key], type: 'number', read: true, write: false });
      
                  // Wert je Datenpunkt aus der API Antwort zuordnen
                  let value = 0;
                  switch (key) {
                      case 'total': value = data.queries.total; break;
                      case 'blocked': value = data.queries.blocked; break;
                      case 'percent_blocked': value = Math.round(data.queries.percent_blocked); break;
                      case 'unique_domains': value = data.queries.unique_domains; break;
                      case 'queries_forwarded': value = data.queries.forwarded; break;
                      case 'queries_cached': value = data.queries.cached; break;
                      default: value = 666;
                  }
      
                  debugLog(`${dp}: ${value}`);
                  setState(dp, value || 0, true);
              }
      
              if (debug) console.log('✅ Pi-hole Daten aktualisiert');
      
          } catch (err) {
              log('❌ Fehler bei Pi-hole API Zugriff: ' + err.message, 'error');
          }
      }
      
      // ⏰ Intervall: alle 5 Minuten ausführen
      schedule('*/5 * * * *', loginAndFetchPiHole);
      // Direkt beim Start einmal ausführen
      loginAndFetchPiHole();
      
      

      Ich will hier keine Grundsatzdiskussion über Arten der Programmierung oder gar die Adapterentwicklung in Frage stellen. Das Script läuft bei mir, wenn es jemanden hilft, gut, wenn nicht, auch gut.

      CU

      posted in Error/Bug
      ceng
      ceng
    • RE: Löschen von Objekten in Aufzählungen [solved]

      Danke @paul53
      Danke für den Support @paul53

      Mittlerweile bin ich nach rumprobieren da...

          if(existsObject('enum.rooms.' + RaumnameAmDevice)) {
              console.log('Raum ' + RaumnameAmDevice + ' vorhanden');
              let obj = getObject('enum.rooms.' + RaumnameAmDevice)
              if(obj.common.members.includes(DP_Selected)) {
                  console.log('DP ist in Raumaufzählung vorhanden. Obj ' + JSON.stringify(obj));
                  let idx = obj.common.members.indexOf(DP_Selected);
                  console.log(DP_Selected + ' ist in der Aufzählung für ' + RaumnameAmDevice + ' an Stelle ' + idx);          
                  if(idx > -1) {
                      console.warn('Lösche ' + DP_Selected + ' ID:' + idx);
                      obj.common.members.splice(idx, 1);
                      setObject('enum.rooms.' + RaumnameAmDevice, obj, function (err) {
                          if (err) console.error('Fehler: Lösche ID ' + idx + ' | DP ' + DP_Selected + ' aus Aufzählung  ' + String(RaumnameAmDevice) + ' fehlgeschlagen. Error=' + err, 'error');
                      });
                      if (getState('0_userdata.0.Global.Debug').val == true) {
                          console.log(('Raumzuweisung für DP_Selected: ' + DP_Selected + ' | RaumAmDevice: ' + RaumnameAmDevice + '  RaumAmDP '+ RaumnameAmDP + ' gelöscht'));
                      }
      
                  }
              } else {
                  console.log(DP_Selected + ' ist nicht Aufzählung vorhanden');
              }
          } else {
              if (getState('0_userdata.0.Global.Debug').val == true) {
                  console.log(('Raum ' + RaumnameAmDevice + ' ist nicht in Aufzählung vorhanden. DP Selected:' + DP_Selected));
              }   
          }
      
      posted in JavaScript
      ceng
      ceng
    • RE: Löschen von Objekten in Aufzählungen [solved]

      @paul53
      Erstmal vielen Dank für Deine Hilfe.

      Ich erhalte jetzt allerdings Fehler beim Objekt:

      08:52:22.977	info	javascript.4 (940122) script.js.Test.Test_SYNC_Sonof: Function #DP Raum zuweisen#: DP_Selected: 0_userdata.0.Lokal.Schalten.Aussen.Garten.Farbwechsler_Gartenlampe Slave 1 Freisitz_POWER1 | Raum: Garten
      08:52:22.980	error	javascript.4 (940122) script.js.Test.Test_SYNC_Sonof: ReferenceError: common is not defined
      08:52:22.980	error	javascript.4 (940122) at DP_Raum_zuweisen (script.js.Test.Test_SYNC_Sonof:272:19)
      08:52:22.980	error	javascript.4 (940122) at Object.<anonymous> (script.js.Test.Test_SYNC_Sonof:473:15)
      

      Die Zeile 272 ist

       let idx = common.members.indexOf(DP_Selected);
      

      Das Script habe ich nach Deiner Vorlage angepasst:

      //Löschen
      let obj = getObject('enum.rooms.' + String(RaumnameAmDevice))
      if(existsObject('enum.rooms.' + String(RaumnameAmDevice))) {
          let idx = common.members.indexOf(DP_Selected);
          if(idx > -1) {
              console.log('Lösche ' + DP_Selected);
              obj.common.members.splice(idx, 1);
              setObjectAsync('enum.rooms.' + RaumnameAmDevice, idx, function (err) {
                  if (err) log('Fehler: Löschen von ' + String(DP_Selected) + ' am  ' + String(RaumnameAmDevice) + ' fehlgeschlagen. Error=' + err, 'error');
              });
          }
      }
      
      posted in JavaScript
      ceng
      ceng
    • RE: Löschen von Objekten in Aufzählungen [solved]

      @paul53 sagte in Löschen von Objekten in Aufzählungen:

                                                                                                                                      if(!obj.common.members.includes(DP_Selcted) {                                                                                                                                                                                    obj.common.members.push(DP_Selected);                                                                                                                                                                                    setObject(...);                                                                                                                                                                                }                                            
      

      THX Paul

      Bleibt noch Frage 1 und 3. Hat jemand eine Idee

      posted in JavaScript
      ceng
      ceng
    • Löschen von Objekten in Aufzählungen [solved]

      Hallo Ihr,
      Problem: Objekt (POWER1) wird in Aufzählung (Rooms) bei jedem Script Start angelegt.

      Ich erstelle per Script Datenpunkte die auf Basis des Friendly Name eine bessere Übersicht in "userdata.0.schalten" bieten. So kann ich ein physisches Device einfach tauschen, ohne den Rest anzupassen. => Gleicher Friendlyname am Sonoff Device und der Rest funktioniert wieder.

      Wenn ich das untenstehende Script nutze, wird mir aber der neue Datenpunkt mehrfach in die Aufzählung "rooms" gepusht.

      1.) Wie kann ich aus einer Aufzählung löschen, wenn das Device sich vom Raum A in Raum B bewegt. Mein Script lässt das Objekt in Raum A weiter stehen.
      2.) Wie kann ich abprüfen, ob das Objekt bereits in der Aufzählung vorhanden ist und dann entweder anlegen oder nichts machen -> Hat Paul53 gelöst. THX
      3.) Wie kann ich sicherstellen, dass die Objekte wirklich angelegt werden. Vgl. Zeile 8 im Script. Hier habe ich nach Ausführung des Scripts eine Pause von 1 Sekunden eingebaut. Das funktioniert, ist aber vermutlich optimierungsfähig.

      if(!existsObject('enum.rooms.' + String(Raumname))) {
          console.log('Raumname ' + String(Raumname) + ' NICHT in Aufzählung');
      } else {
          let obj = getObject('enum.rooms.' + String(Raumname))
         // hier ist das PROBLEM -> Objekt wird IMMER zusätzlich angelegt
          obj.common.members.push(DP_Selected);
          //https://forum.iobroker.net/topic/50900/getobject-setobject-bug/4
          setObjectAsync('enum.rooms.' + String(Raumname), obj, function (err) {
                  if (err) console.log('Fehler: Zuordnung von ' + String(DP_Selected) + ' zu  ' + String(Raumname) + ' fehlgeschlagen. Error=' + err, 'error');
          });
      }
      

      Gruß
      CENG

      posted in JavaScript
      ceng
      ceng
    • RE: ID Selektor - Welche ID hat die Änderung verursacht? DONE

      @liv-in-sky Danke, wie kann man so blind sein, dass zu übersehen... Reingezogen tut...

      Vielen Dank

      posted in JavaScript
      ceng
      ceng
    • ID Selektor - Welche ID hat die Änderung verursacht? DONE

      Hallo Community,
      ich möchte mir anzeigen lassen, welche Objekt ID eine Änderung im System ausgelöst hat.
      Dafür nutze ich das Blockly "Falls Objekt > IDs vom Selektor $(stateid=sonoff.0..POWER}
      Das funktioniert auch prinzipiell. Wenn ein Sonoff den Status Power ändert, wird das Script gestartet.
      ABER... Wenn ich mir jetzt die Objekt ID anzeigen lassen will, die die Änderung ausgelöst hat, bin ich völlig lost.

      Hat jemand eine Idee?
      Liebe Grüße
      CENG

      Mein aktuelle Stand: Screenshot 2022-11-30 081608.png

      posted in JavaScript
      ceng
      ceng
    • Grillthermometer WROOM32

      Hallo,
      nachdem jetzt einige Stunden in die Lösung geflossen sind, möchte ich mein Ergebnis dazu teilen.

      Grillthermometer haben die Problematik, dass sie natürlich Temperaturen von weit über 200 Grad Celsius aushalten müssen. Mit den herkömmlichen Senosren DHT, AMS, HTU usw. komme ich da nicht ans Ziel.

      Die Lösung war einfach gefunden.
      ein MAX 6675 mit einer NodeMCU Wroom32
      MAX 6675 bei Amazon
      NodeMCU Wroom32 bei Amazon

      Aber dann ging es los... Welche Einstellungen... Nichts im Netz gefunden. Vll. gibt es dann ja hier in den Kommentaren Hinweise auf andere Hilfeseiten.

      1. PINOUT:

      Pinout WROOM32 zu MAX6675:
      GND -----------> GND
      3V3 ------------> VCC
      D5 ------------> SO
      D19 ------------> CS
      D23 ------------> SCK
      PinoutGrillThermometerMax6675.png

      2. Config
      Kommen wir zu den Einstellungen auf der Tasmota Seite...

      • Öffnen der Tasmota Konsole und Eingabe von SetOption94 1 Vgl. Tasmota Command
        Console 94 1.PNG
      • Template über "Einstellungen\Sonstige Konfiguration" anpassen auf
        {"NAME":"CENG Wroom32FORMAX6675","GPIO":[0,0,320,0,0,2560,1,1,0,1,1,1,0,1,0,2496,0,640,608,2528,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
        Template.PNG
        *Alternativ über "Einstellungen\Vorlage konfigurieren" die Einstellungen vornehmen:
        Vorlage.PNG

      Jetzt sollte der Eintrag für den MAX6675 auf der Hauptseite erscheinen
      Hauptseite.PNG

      Immer noch keine Temperatur Anzeige?
      Ich habe gelernt, dass es ggf. notwendig ist, seine eigene Tasmota Version zu kompilieren. Hierzu guck mal unter Gitpod / Tasmota.

      posted in Off Topic
      ceng
      ceng
    • RE: Sonoff Adapter bleibt Gelb [solved]

      An Alle...

      Ähhhh...
      Die Clients sind alle wie vorher, bis auf den tasmota_54A582. Den habe ich ja gerade mit @Ralla66 umgestellt. An den Nodes habe ich NICHTS umgestellt.

      Jetzt sind beide Adapter. Sowohl der Sonoff als auch der MQTT auf grün.

      Warum? Gute Frage... Gemacht haben wir eigentlich nichts...

      Macht nix. Beide grün, alles gut. Danke für Eure Hilfen und Ideen.

      posted in ioBroker Allgemein
      ceng
      ceng
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo