Navigation

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

    NEWS

    • Monatsrückblick – September 2025

    • Neues Video "KI im Smart Home" - ioBroker plus n8n

    • Neues Video über Aliase, virtuelle Geräte und Kategorien

    U
    • Profile
    • Following 0
    • Followers 0
    • Topics 5
    • Posts 28
    • Best 0
    • Groups 1

    undeat

    @undeat

    -1
    Reputation
    58
    Profile views
    28
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    undeat Follow
    Starter

    Latest posts made by undeat

    • RE: Internet Filter in der Fritzbox mit JavaScript setzen

      Hallo Leute,

      Das Thema ist zwar sehr alt, aber ich habe es heute wieder einmal heraus gekramt, weil ich genau das brauchte. Vielen Dank für alles.

      Es hat zuerst ganz gut Funktioniert. Das einzige, was doof war, war das der JavaScript Editor die match Variable nicht erkannt hat und diese als Fehler im Skript dargestellt wurden. Das konnte man recht einfach mit mit "var match;" vor jeder Verwendungsstelle, die Variable erst einmal definiert.

      Also zweites hatte ich dann bei bestimmten Geräten auch das Problem, dass mir die Sperren an den falschen Geräten eingestellt wurden. Hier ist das Problem das Folgende. Die Filter müssen auf Basis der Geräte ID gesetzt werden. Für die Einfachere Handhabbarkeit wird im Skript aber der Gerätename angegeben. Das Skript fragt daher vorher zu dem Gerätenamen die ID ab.
      Dabei wird einer Liste aller Gerätenamen mit zugehöriger ID angelegt. Wenn man auf fBListOnly = true setzt, dann sieht man diese Liste auch. Leider kann man aber hier schlecht nachvollziehen, ob diese Liste stimmt. Jedenfalls stimmte diese Liste bei mir nicht. Es gab einen Versatz. Bei mir wurde dieser ausgelöst durch eine "()" im Namen.

      Fehlerbehebung:

      Zeile 210:

      var rx = new RegExp( /class=\"name\"\stitle=\"([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"\sdatalabel/g );
      

      druch

      var rx = new RegExp( /class=\"name\"\stitle=\"([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"\sdatalabel/g ) ;
      

      ersetzen!

      Desweiteren ist die request Funktion veraltet. Das wirft jedes Mal eine Warnung, wenn man das Skript startet.
      Da fingen die Probleme dann richtig an. Ich kann zwar grundsätzlich Programmieren, aber diese tiefen vom Java Script und den Webapplikationen gehen dann doch weit über mein Wissen hinaus. Ich beschreibe das mal so, wie ich es mir zusammengereimt habe.

      anstatt request.get soll man httpGet() oder anstatt request.post http.Post() verwenden. Eins zu eins tauschen ist nicht. Also habe ich etwas gegoogelt und ChatGpt befragt, aber irgendwie war die Funktion nicht so, wie sie zu erwarten war. Das Problem hier war, dass das so genannte axios irgendwo im Iobroker installiert ist und die standard httpGet und httpPost Funktionen überschreibt. Die neuen Funktionen funktionieren dann anders, weil es axios ist.

      Als ich dann soweit erstmal war, hat ChatGpt mir ganz gut geholfen, alle requst zu ersetzen. Wichtig ist, dann man oben dieses

      request = require("request")
      

      dann auch noch entfernt, weil sonst die Warnung weiterhin auftaucht.

      Die neuen httpGet() Funktionen bekommen die Werte nicht mehr alle in einer Struct sondern als einzelne Parameter. Auch die Rückgabewerte vom Body sind etwas woanders. Es gibt keine drei Rückgabewerte mehr im Callback, sondern nur noch zwei und der response (zweiter Wert) hat den alten "body" dann unter response.data.

      Da ich sehr viele Geräte in meiner Fritzbox habe, musste ich zudem bei einem httpPost() von getfBDevices das Timeout noch erhöhen. Das war ein hartes Stück Arbeit, dass alles heraus zu bekommen, aber ChatGPT ist echt erstaunlich und hat viel geholfen.

      Ich füge mein neues Skipt jetzt hier ein. Es ist leider komplett Umgebaut, weil ich es als Klasse haben wollte. Ich arbeitet generell in meinen Skripten viel mit Klassen.

      So habe ich eine Klasse "VirtuellesGerät". Wenn ich davon eine Instanz erzeuge, kann ich einen Namen übergeben. Unter diesem Namen wird dann ein Datenpunkt angelegt. Mit einer Methode setCallback(function()) kann ich dem Objekt dann direkt ein Callback geben, welches aufgerufen wird, wenn sich der Datenpunkt ändert. Ich kann so auch sehr einfach ein und Ausschaltzeiten für das Gerät definieren, weil meine Klasse das alles kann. Diese Zeiten schalten auch den Datenpunkt, wodurch dann der Callback ebenfalls ausgelöst wird.

      Daher wollte ich für meine ganzen Fritzbox Geräte, die ich Sperren möchte, eines meiner Virtuellen Geräte angelegen und im Callback dann die Methode meiner neuen Fritzbox Klasse aufrufen, um die Internetsperre ein oder auszuschalten.

      Hier daher mein Funktionierenden Fritzbox Klassen Skript als Unterstützung zum Nachbauen der von mir oben beschriebenen Änderungen.

      class FritzBox
      {
          Ip;
          User;
          Password;
          Debug;
          Liste;
          Active;
      
          headers;
          secChallenge;
          secMd5;
          secLogin;
          secSid;
          secProfileNames = [];
          secProfileIds   = [];
          secDeviceNames  = [];
          secDeviceIds    = [];
          JsonList        = "";
          hexcase = 0;   /* hex output format. 0 - lowercase; 1 - uppercase        */
          b64pad  = "";  /* base-64 pad character. "=" for strict RFC compliance   */
      
          InternetAn = "filtprof3";
          InternetAus = "filtprof1371";
      
          Debugging = false;
          ListOnly = false;
          CreateList = false;
      
          constructor (IP,User,Password,Debug = false)
          {
              this.Ip = IP;
              this.User = User;
              this.Password = Password;
              this.log("Fritzbox für IP: " + this.Ip + " erstellt");
              this.Debug = Debug;
              this.Liste = new Map();
              this.Active = false;
              this.headers = { 
                                  'Content-Type': 'application/x-www-form-urlencoded', 
                                  'User-Agent': 'curl/7.64.0', 
                                  'Accept': '*/*'
                              }; 
      
              if (this.ListOnly)
              {
                  this.getFbChallenge();
              }
          }
      
          log(Message)
          {
              if (this.Debug)
              {
                  console.log("FritzBox: " + Message);
              }
          }
      
          EintagHinzufuegen(name, state) 
          {
              this.Liste.set(name, state);
              if (!this.Active)
              {
                  this.Active = true;
                  this.CheckListe();
              }
          }
      
          CheckListe()
          {
              if (this.Liste.size != 0)
              {
                  const [name, state] = this.Liste.entries().next().value;
                  this.SetDevice(name, state);
                  this.log("Set Device: " + name);
              }
              else
              {
                  this.Active = false;
              }
          }
      
          SetDevice(Device,Internet)
          {
              this.Device = Device;
              if (Internet)
              {
                  this.Profile = this.InternetAn;
              }
              else
              {
                  this.Profile = this.InternetAus;
              }
              this.getFbChallenge();
          }
      
          hex_md5(s)    { return this.rstr2hex(this.rstr_md5(this.str2rstr_utf8(s))); }
          b64_md5(s)    { return this.rstr2b64(this.rstr_md5(this.str2rstr_utf8(s))); }
          any_md5(s, e) { return this.rstr2any(this.rstr_md5(this.str2rstr_utf8(s)), e); }
          
          hex_hmac_md5(k, d)
          { return this.rstr2hex(this.rstr_hmac_md5(this.str2rstr_utf8(k), this.str2rstr_utf8(d))); }
          b64_hmac_md5(k, d)
          { return this.rstr2b64(this.rstr_hmac_md5(this.str2rstr_utf8(k), this.str2rstr_utf8(d))); }
          any_hmac_md5(k, d, e)
          { return this.rstr2any(this.rstr_hmac_md5(this.str2rstr_utf8(k), this.str2rstr_utf8(d)), e); }
       
          /*
          * Perform a simple self-test to see if the VM is working
          */
          md5_vm_test()
          {
          return this.hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72";
          }
       
          /*
          * Calculate the MD5 of a raw string
          */
          rstr_md5(s)
          {
          return this.binl2rstr(this.binl_md5(this.rstr2binl(s), s.length * 8));
          }
       
          /*
          * Calculate the HMAC-MD5, of a key and some data (raw strings)
          */
          rstr_hmac_md5(key, data)
          {
          var bkey = this.rstr2binl(key);
          if(bkey.length > 16) bkey = this.binl_md5(bkey, key.length * 8);
          
          var ipad = Array(16), opad = Array(16);
          for(var i = 0; i < 16; i++)
          {
              ipad[i] = bkey[i] ^ 0x36363636;
              opad[i] = bkey[i] ^ 0x5C5C5C5C;
          }
          
          var hash = this.binl_md5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8);
          return this.binl2rstr(this.binl_md5(opad.concat(hash), 512 + 128));
          }
       
          /*
          * Convert a raw string to a hex string
          */
          rstr2hex(input)
          {
          try { this.hexcase } catch(e) { this.hexcase=0; }
          var hex_tab = this.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
          var output = "";
          var x;
          for(var i = 0; i < input.length; i++)
          {
              x = input.charCodeAt(i);
              output += hex_tab.charAt((x >>> 4) & 0x0F)
                  +  hex_tab.charAt( x        & 0x0F);
          }
          return output;
          }
       
          /*
          * Convert a raw string to a base-64 string
          */
          rstr2b64(input)
          {
          try { this.b64pad } catch(e) { this.b64pad=''; }
          var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
          var output = "";
          var len = input.length;
          for(var i = 0; i < len; i += 3)
          {
              var triplet = (input.charCodeAt(i) << 16)
                          | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
                          | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
              for(var j = 0; j < 4; j++)
              {
              if(i * 8 + j * 6 > input.length * 8) output += this.b64pad;
              else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
              }
          }
          return output;
          }
       
          /*
          * Convert a raw string to an arbitrary string encoding
          */
          rstr2any(input, encoding)
          {
          var divisor = encoding.length;
          var i, j, q, x, quotient;
          
          /* Convert to an array of 16-bit big-endian values, forming the dividend */
          var dividend = Array(Math.ceil(input.length / 2));
          for(i = 0; i < dividend.length; i++)
          {
              dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
          }
          
          /*
          * Repeatedly perform a long division. The binary array forms the dividend,
          * the length of the encoding is the divisor. Once computed, the quotient
          * forms the dividend for the next step. All remainders are stored for later
          * use.
          */
          var full_length = Math.ceil(input.length * 8 /
                                              (Math.log(encoding.length) / Math.log(2)));
          var remainders = Array(full_length);
          for(j = 0; j < full_length; j++)
          {
              quotient = Array();
              x = 0;
              for(i = 0; i < dividend.length; i++)
              {
              x = (x << 16) + dividend[i];
              q = Math.floor(x / divisor);
              x -= q * divisor;
              if(quotient.length > 0 || q > 0)
                  quotient[quotient.length] = q;
              }
              remainders[j] = x;
              dividend = quotient;
          }
          
          /* Convert the remainders to the output string */
          var output = "";
          for(i = remainders.length - 1; i >= 0; i--)
              output += encoding.charAt(remainders[i]);
          
          return output;
          }
          
          /*
          * Encode a string as utf-8.
          * For efficiency, this assumes the input is valid utf-16.
          */
          str2rstr_utf8(input)
          {
          var output = "";
          var i = -1;
          var x, y;
          
          while(++i < input.length)
          {
              /* Decode utf-16 surrogate pairs */
              x = input.charCodeAt(i);
              y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
              if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
              {
              x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
              i++;
              }
          
              /* Encode output as utf-8 */
              if(x <= 0x7F)
              output += String.fromCharCode(x);
              else if(x <= 0x7FF)
              output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
                                              0x80 | ( x         & 0x3F));
              else if(x <= 0xFFFF)
              output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
                                              0x80 | ((x >>> 6 ) & 0x3F),
                                              0x80 | ( x         & 0x3F));
              else if(x <= 0x1FFFFF)
              output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
                                              0x80 | ((x >>> 12) & 0x3F),
                                              0x80 | ((x >>> 6 ) & 0x3F),
                                              0x80 | ( x         & 0x3F));
          }
          return output;
          }
      
      
          str2rstr_utf16le(input)
          {
          var output = "";
          for(var i = 0; i < input.length; i++)
              output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
                                          (input.charCodeAt(i) >>> 8) & 0xFF);
          return output;
          }
       
          str2rstr_utf16be(input)
          {
          var output = "";
          for(var i = 0; i < input.length; i++)
              output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
                                          input.charCodeAt(i)        & 0xFF);
          return output;
          }
      
          rstr2binl(input)
          {
          var output = Array(input.length >> 2);
          for(var i = 0; i < output.length; i++)
              output[i] = 0;
          for(var i = 0; i < input.length * 8; i += 8)
              output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
          return output;
          }
          
          /*
          * Convert an array of little-endian words to a string
          */
          binl2rstr(input)
          {
          var output = "";
          for(var i = 0; i < input.length * 32; i += 8)
              output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
          return output;
          }
          
          /*
          * Calculate the MD5 of an array of little-endian words, and a bit length.
          */
          binl_md5(x, len)
          {
          /* append padding */
          x[len >> 5] |= 0x80 << ((len) % 32);
          x[(((len + 64) >>> 9) << 4) + 14] = len;
          
          var a =  1732584193;
          var b = -271733879;
          var c = -1732584194;
          var d =  271733878;
          
          for(var i = 0; i < x.length; i += 16)
          {
              var olda = a;
              var oldb = b;
              var oldc = c;
              var oldd = d;
          
              a = this.md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
              d = this.md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
              c = this.md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
              b = this.md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
              a = this.md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
              d = this.md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
              c = this.md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
              b = this.md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
              a = this.md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
              d = this.md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
              c = this.md5_ff(c, d, a, b, x[i+10], 17, -42063);
              b = this.md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
              a = this.md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
              d = this.md5_ff(d, a, b, c, x[i+13], 12, -40341101);
              c = this.md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
              b = this.md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
          
              a = this.md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
              d = this.md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
              c = this.md5_gg(c, d, a, b, x[i+11], 14,  643717713);
              b = this.md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
              a = this.md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
              d = this.md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
              c = this.md5_gg(c, d, a, b, x[i+15], 14, -660478335);
              b = this.md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
              a = this.md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
              d = this.md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
              c = this.md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
              b = this.md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
              a = this.md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
              d = this.md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
              c = this.md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
              b = this.md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
          
              a = this.md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
              d = this.md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
              c = this.md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
              b = this.md5_hh(b, c, d, a, x[i+14], 23, -35309556);
              a = this.md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
              d = this.md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
              c = this.md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
              b = this.md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
              a = this.md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
              d = this.md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
              c = this.md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
              b = this.md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
              a = this.md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
              d = this.md5_hh(d, a, b, c, x[i+12], 11, -421815835);
              c = this.md5_hh(c, d, a, b, x[i+15], 16,  530742520);
              b = this.md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
          
              a = this.md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
              d = this.md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
              c = this.md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
              b = this.md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
              a = this.md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
              d = this.md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
              c = this.md5_ii(c, d, a, b, x[i+10], 15, -1051523);
              b = this.md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
              a = this.md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
              d = this.md5_ii(d, a, b, c, x[i+15], 10, -30611744);
              c = this.md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
              b = this.md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
              a = this.md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
              d = this.md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
              c = this.md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
              b = this.md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
          
              a = this.safe_add(a, olda);
              b = this.safe_add(b, oldb);
              c = this.safe_add(c, oldc);
              d = this.safe_add(d, oldd);
          }
          return Array(a, b, c, d);
          }
          
          /*
          * These functions implement the four basic operations the algorithm uses.
          */
          md5_cmn(q, a, b, x, s, t)
          {
          return this.safe_add(this.bit_rol(this.safe_add(this.safe_add(a, q), this.safe_add(x, t)), s),b);
          }
      
          md5_ff(a, b, c, d, x, s, t)
          {
          return this.md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
          }
      
          md5_gg(a, b, c, d, x, s, t)
          {
          return this.md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
          }
      
          md5_hh(a, b, c, d, x, s, t)
          {
          return this.md5_cmn(b ^ c ^ d, a, b, x, s, t);
          }
      
          md5_ii(a, b, c, d, x, s, t)
          {
          return this.md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
          }
          
          /*
          * Add integers, wrapping at 2^32. This uses 16-bit operations internally
          * to work around bugs in some JS interpreters.
          */
          safe_add(x, y)
          {
          var lsw = (x & 0xFFFF) + (y & 0xFFFF);
          var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
          return (msw << 16) | (lsw & 0xFFFF);
          }
          
          /*
          * Bitwise rotate a 32-bit number to the left.
          */
          bit_rol(num, cnt)
          {
          return (num << cnt) | (num >>> (32 - cnt));
          }
      
          getFbChallenge()
          {
              this.log("function getFbChallenge");
              httpGet
              ('http://' + this.Ip + '/login_sid.lua?username=' + this.User,{
                  headers:    this.headers
                  }, (error, body) => {
                  if (error) log(error, 'error');
                  this.log(body.data);
                  // https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/RegExp
                  // <?xml version="1.0" encoding="utf-8"?><SessionInfo><SID>0000000000000000</SID><Challenge>d36de231</Challenge><BlockTime>0</BlockTime><Rights></Rights></SessionI
                  this.secChallenge = body.data.match(/Challenge>(.*)<\/Challenge/)[1];
                  this.log(" > Challenge : " + this.secChallenge);
          
                  var uft16le = this.str2rstr_utf16le(this.secChallenge + "-" + this.Password );
                  var md5     = this.rstr_md5(uft16le);
                  this.secMd5      = this.rstr2hex(md5);
                          
                  this.log(" > MD5       : " + this.secMd5);   
          
                  // response="${challenge}-${md5}"
                  // sid=$(curl -i -s -k -d "response=${response}&username=" "http://$1" | grep -Po -m 1 '(?<=sid=)[a-f\d]+' | tail -1)
                  this.secLogin = "response=" + this.secChallenge + "-" + this.secMd5 + "&username=" + this.User;
          
                  this.log(" > Login     : " + this.secLogin);
          
                  this.getFbSid();
              });
          }
      
      
          // Get the SID from the Fritzbox
          getFbSid() {
              this.log("function getFbSid");
              //this.log('httpPost typeof: ' + typeof httpPost);
              //this.log('httpPost function content:\n' + httpPost.toString());
              httpPost('http://' + this.Ip + '/login_sid.lua',
              this.secLogin,
              {     
                  headers:  this.headers
              }, (error, response ) => {
                  this.log(response.data);
                  if (error) log(error, 'error');
                  // SID filtern 
                  // "sid":"c503b24dae458086"
                  try {
                      //this.secSid = response.data.match(/\"sid\":\"(.*)\"/)[1];
                      this.secSid = response.data.match(/<SID>(.*?)<\/SID>/)[1];
                  }
                  catch (e) {
                      if (this.secSid == undefined) {
                          this.log("Your login was not successful. End Script " + Error)
                          return;
                      }
                  }
          
                  this.log(" > SID       : " + this.secSid);
          
                  //getFbDeviceInfos();
                  this.getFbProfiles();
              });
          } 
          
          // TBD: 
          // Netzwerkinfos mit allen Devices lesen: 
          // var req = "xhr=1&sid=" + secSid + "&lang=de&page=netDev&xhrId=cleanup&useajax=1&no_sidrenew=" 
          getFbDeviceInfos(){
              this.log("function getFbDeviceInfos");
              var req = "xhr=1&sid=" + this.secSid + "&lang=de&page=netDev&xhrId=cleanup&useajax=1&no_sidrenew=" 
          
              httpPost('http://' +this.Ip + '/data.lua',req,
              {
                  headers:    this.headers 
              }, (error, response) => {
                  if (error) log(error, 'error');
                  this.log(response.data);
              });    
          }
       
          // Get all Profiles from the Fritzbox
          getFbProfiles() {
              this.log("function getFbProfiles");
              // #curl -d "xhr=1&sid=${sid}&lang=de&no_sidrenew=&page=kidPro" "http://$1/data.lua"
              var req = "xhr=1&sid=" + this.secSid + "&lang=de&no_sidrenew=&page=kidPro";
              var match;
          
              httpPost('http://' + this.Ip + '/data.lua',req,
              {
                  headers:    this.headers, 
              }, (error, response) => {
                  if (error) log(error, 'error');
                  
                  if (this.Debugging){
                      this.log(" > response.body : \n" + response.data);
                  }
          
                  this.secProfileIds   = [];
                  this.secProfileNames = [];
          
                  this.log(" > Decode Names")
                  var rx = new RegExp( /class=\"name\"\stitle=\"([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"\sdatalabel/g );
                  while( (match = rx.exec( response.data )) != null ) {
                      this.secProfileNames.push(match[1]);
                  }
                  if (this.Debugging){
                      this.log(" > secProfileNames : \n" + this.secProfileNames);
                  }
          
                  this.log(" > Decode Filters")
                  // submit" name="edit" value="
                  rx = new RegExp( /submit\"\sname=\"edit\"\svalue=\"([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"\sclass=\"icon/g );
                  while( (match = rx.exec( response.data )) != null ) {
                      this.secProfileIds.push(match[1]);
                  }
                  if (this.Debugging){
                      this.log(" > secProfileIds : \n" + this.secProfileIds);
                  }
          
                  if (this.ListOnly) {
                      this.log("Filter Count : " + this.secProfileIds.length);
                      for (var i = 0; i < this.secProfileIds.length; i++) {
                          this.log("Filter named '"+ this.secProfileNames[i] + "' has ID : " + this.secProfileIds[i]);
                      }
                  }
          
                  this.getFbDevices();
              });
          }
       
          // IMPORTANT: 
          // The DeviceId changes when you switch the profile. 
          // If you use default profiles it is something like "landevice308962"
          // If you use your own profiles it is something like "user7749"
          getFbDevices() {
              this.log("function getFbDevices");
              var match;
              // xhr=1&sid=5f5ba302815594d8&lang=de&no_sidrenew=&page=kidLis
              var req = "xhr=1&sid=" + this.secSid + "&lang=de&no_sidrenew=&page=kidLis";
      
              httpPost('http://' + this.Ip + '/data.lua',req,
              {
                  headers:  this.headers,
                  timeout: 10000
              }, (error, response) => {
                  if (error) this.log("HTTP Fehler: " + error);
                  if (this.Debugging){
                      this.log(" > response.data : \n" + response.data);
                  }
          
                  // TESTING
                  //body = getState("Global.0.Testing.StringValue").val;
          
                  this.secDeviceNames = [];
                  this.secDeviceIds   = [];
          
                  this.log(" > Decode Device Names")
                  var rx = /class=\"name"\stitle=\"([^"]*)\"\sdatalabel/g;
                  //var rx = new RegExp( /class=\"name"\stitle=\"([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"\sdatalabel/g );
                  while( (match = rx.exec( response.data )) != null ) {
                      this.secDeviceNames.push(match[1]);
                  }
                  if (this){
                      this.log(" > secDeviceNames : \n" + this.secDeviceNames);
                  }
          
                  this.log(" > Decode Device Ids")
                  
                  rx = new RegExp( /name=\"profile:([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"><option/g );
                  while( (match = rx.exec( response.data )) != null ) {
                      this.secDeviceIds.push(match[1]);
                  }
                  if (this.Debugging){
                      this.log(" > secDeviceIds : \n" + this.secDeviceIds);
                  }
                  
                  if (this.ListOnly) {
                      this.log("Device Count : " + this.secDeviceIds.length);
                      for (var i = 0; i < this.secDeviceNames.length; i++) {
                          this.log(i + " - Device named '"+ this.secDeviceNames[i] + "' has ID : " + this.secDeviceIds[i]);
                      }
                  }
          
                  if (!this.ListOnly) { 
                      this.setFbSperre(); 
                  } else { 
                      this.log("DONE : Listmode - No Device blocking ..."); 
                  }
              });
          }
       
          //curl -d "sid=${sid}&edit=$3&time=$4&budget=unlimited&apply=&page=kids_profileedit" "http://$1/data.lua" >/dev/null 2>&1
          setFbSperre() {
              this.log("function setFbSperre");
              
              // Device suchen ... 
              var devId = -1;
              for (var i = 0; i < this.secDeviceNames.length; i++) {
                  if (this.secDeviceNames[i] == this.Device) {
                      devId = i;
                  }
              }
              
              this.log(" > Device Nr   : " + devId); 
              this.log(" > Device ID   : " + this.secDeviceIds[devId]); 
              this.log(" > Device Name : " + this.secDeviceNames[devId]);
              //var profile = "filtprof4";
              //var profile = "filtprof3079";
          
              // xhr=1&sid=b46f3d48b3b0fcc2&lang=de&no_sidrenew=&profile%3Alandevice308962=filtprof4&apply=&oldpage=%2Finternet%2Fkids_userlist.lua
              var req2 = "xhr=1&sid=" + this.secSid + "&lang=de&no_sidrenew=&profile%3A" + this.secDeviceIds[devId] + "=" + this.Profile + "&apply=&oldpage=%2Finternet%2Fkids_userlist.lua";
              this.log(" > req : " + req2);
      
              httpPost('http://' + this.Ip + '/data.lua',req2,
              {
                  headers:    this.headers, 
              }, (error, response) => {
                  if (error) log(error, 'error');
                  if (this.Debugging){
                      this.log(" > response : \n" + response.data);
                  }
          
                  this.log("Change done. Check your FB / Device if it worked :-)");
                  this.Liste.delete(this.Device);
                  this.CheckListe();
                  if (this.CreateList) {
                      this.getFbDeviceFilterList();
                  }
              });      
          }
          
          getFbDeviceFilterList() {
              this.log("function getFbDeviceFilterList");
              
              // xhr=1&sid=e2d99419592fb780&lang=de&no_sidrenew=&page=kidLis
              var req = "xhr=1&sid=" + this.secSid + "&lang=de&no_sidrenew=&page=kidLis";
              var match;
          
              httpPost('http://' + this.Ip + '/data.lua',req,
              {
                  headers:    this.headers, 
              }, (error, response) => {
                  //if (error) log(error, 'error');
                  //this.log(response.body);
          
                  this.JsonList = "";
                  var tmpDevices      = [];
                  var tmpUsage        = [];
                  var tmpProfilesId   = [];
                  var tmpProfilesName = [];
                  var tmpTimes        = [];
          
                  // TESTING
                  //body = getState("Global.0.Testing.StringValue").val;
                  
                  this.log(" > Decode Device Names")
                  var rx = new RegExp(/class=\"name"\stitle=\"([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"\sdatalabel/g);
                  while ((match = rx.exec(response.data)) != null) {
                      tmpDevices.push(match[1]);
                  }
                  //this.log(" > " + tmpDevices);
          
                  this.log(" > Decode Device Profile ID");
                  //rx = new RegExp(/button\s.*?value=\"([a-zA-Z0-9 äöüÄÖÜ]*?)\"/g);
                  rx = new RegExp(/option\svalue=\"([a-zA-Z0-9 äöüÄÖÜ\-]*?)\"\sselected/g);
                  while ((match = rx.exec(response.data)) != null) {
                      tmpProfilesId.push(match[1]);
                  }
                  //this.log(" > " + tmpProfilesId);
          
                  this.log(" > Decode Device Profile Names");
                  for (var i = 0; i < tmpProfilesId.length; i++) {
                      for (var j = 0; j < this.secProfileIds.length; j++) { 
                          //this.log(tmpProfilesId[i] + " > " + secProfileIds[j]);
                          if (tmpProfilesId[i] == this.secProfileIds[j]){
                              tmpProfilesName.push(this.secProfileNames[j]);
                          }
                      }
                  }
                  //this.log(" > " + tmpProfilesName);
          
                  this.log(" > Decode Internetnutzung")
                  rx = new RegExp(/td\sdatalabel=\"[a-zA-Z0-9 äöüÄÖÜ\-]+\"\sclass=\"usage\">(.*?)<\/td>/g);
                  while ((match = rx.exec(response.data)) != null) { 
                      var tmp = match[1];
                      tmp = tmp.replace("<span>", "").replace("<\/span>", "");
                      tmpUsage.push(tmp);
                  }
                  //this.log(" > " + tmpUsage);
          
                  this.log(" > Decode Times")
                  rx = new RegExp(/td\sdatalabel=\"[a-zA-Z0-9 äöüÄÖÜ\-]+\"\sclass=\"bar\stime\">(.*?)<\/td>/g);
                  while ((match = rx.exec(response.data)) != null) {
                      var tmp = match[1];
                      if (tmp.includes("\"")) {
                          tmp = tmp.replace("<span title=\"", "");
                          tmp = tmp.slice(0, tmp.indexOf("\""));
                          tmpTimes.push(tmp);
                      } else {
                          tmpTimes.push(tmp);
                      }
                  }
                  //this.log(" > " + tmpTimes);
          
                  // this.log("Device Count : " + secDeviceIds.length);
                  this.JsonList = "[";
                  for (var i = 0; i < tmpDevices.length; i++) {
                      this.JsonList += "{";
                      this.JsonList += "\"Device\": \"" + tmpDevices[i] + "\"," 
                      this.JsonList += "\"Profile ID\": \"" + tmpProfilesId[i] + "\","
                      this.JsonList += "\"Profile Name\": \"" + tmpProfilesName[i] + "\","
                      this.JsonList += "\"Usage\": \"" + tmpUsage[i] + "\","
                      this.JsonList += "\"Time\": \"" + tmpTimes[i] + "\""
                      if (i != tmpDevices.length - 1) { this.JsonList += "},"; } else { this.JsonList += "}"; }
                  }
                  this.JsonList += "]";
          
                  this.log("DONE : List generated ...");
              }); 
          }
      };
      
      let _FritzBox = new FritzBox("192.168.2.254","user","passwort",true);
      //_FritzBox.EintagHinzufuegen("TV Schlafzimmer",true);
      

      Ich habe oben im Skript die zwei Profile für InternetAn und InternetAus definiert. Daher kann ich mit "TV Schlafzimmer",true das Internet für den FireTV Stick im Schlafzimmer auf einschalten und mit false ausschalten.

      Ebenfalls sollte berücksichtigt sein, dass Anfragen, die Gleichzeitig kommen, nacheinander abgearbeitet werden.

      So mal eben 4 Stunden Kopfzerbrechen, nur damit die Kinder nicht Heimlich an Fernsehen und Tablet gucken können. (9 und 12 Jahre). Ich denke, jetzt habe ich wieder die Nase vorn aber es wird nicht lange dauern, dann werden die Kinder diese Sperren auch umgehen können, da bin ich mir sicher. Ein ständiger Wettkampf.

      posted in JavaScript
      U
      undeat
    • RE: TP Link Tapo P100

      Hallo zusammen,

      dieser Thread ist zwar schon älter, aber ich bin auf ihn gestoßen, weil das Thema leider immer noch, bzw. wieder aktuell ist.

      Der richtige Tapo Adapter vom iobroker wirft immer Meldungen, sobald ein Gerät nicht vorhanden ist. Meine (neue) P100 funktionieren auch nicht

      Mit dem HAB Adapter habe ich es erst auch nicht zum laufen bekommen. Ich habe es dann direkt mit einem richtigen Homebridge versucht und auch da ging es erst nicht. Hier die Ursachen und lösungen. Die neuen P100, P110 haben eine andere Authentifizierung. Das funktioniert wohl nicht mit npm 20.x mit 22.x funktioniert ist. Außerdem hatte ich als Benutzernamen zwar meine Mail Adresse angegeben, dort aber die Anfangsbuchstaben groß geschrieben. Es funktioniert bei mir nur, wenn alles klein ist. So hat es in der normalen Homebridge funktioniert. Im HAB Adapter habe ich es nicht weiter verfolgt, da ich aufgrund von Inkompatibilität des S7 Adapters mit NPM22 noch auf NPM20 bleiben muss.

      Alexa funktioniert aber nicht zuverlässig. Besonders, wenn viele Schaltvorgänge erfolgen.

      Meine Lösung: Node-Red:

      Node Red habe ich im IOB eh schon installiert gehabt. Dort gibt es einen TP Link Tapo Adapter, der die neue und die alte Authentifizierung kann. Wenn man das installiert, hat man ein TP-Link Tapo Node, mit für den man auch Benutzername (Mail Adresse klein geschrieben), Passwort und IP angeben kann. Außerdem kann man den Mode einstellen (Auf Power on/off). Dann kann mit mit true/false (boolean) die Steckdose schalten. Einen IOB input kann man direkt damit verknüpfen, wenn man einen Boolstate als Topic angibt. Weitere Falle hier: Im Pfad vom Topic dürfen keine Umlaute vorhaben sein.

      Ich habe es auch schon hinbekommen, einen JSON aus den Steckdosen zu bekommen. Den kann man bestimmt auch ins IOB schreiben aber soweit war ich noch nicht. Ich kenne mich damit quasi gar nicht aus.

      posted in Entwicklung
      U
      undeat
    • RE: Ring Doorbell Adapter

      Hallo zusammen.
      Ich bekomme den Ring Adapter leider auch nicht (mehr) ans laufen. Mir ist die Festplatte mit meiner iob installation kaputt gegangen und auf dem Backup gab es den Ring Adapter nicht. Vorher hatte es schon mal funktioniert.

      Jedenfalls ist es jetzt so, dass der Adapter startet und "grün" wird. Der Token funktioniert. Unter Objekts werden einige Datenpunkte angelegt und dort sind auch die von mir vergebenen Namen vorhanden, also muss der Login funktioniert haben. Leider gibt es unter Events nur das motion event und auch das funktioniert leider nicht.

      Ich hab kein Abo mehr. Als es noch funktionierte vor dem Festplatten Crash war das Gratis Probeabo noch aktiv.

      Ich habe den Adapter auch Debug gestellt. Dort wird aber auch gar nichts in die Logs eingetragen, wenn ich klingel oder wenn ein motion event kommt.

      Ich vermute, dass die ring-client-api im Adapter erneuert werden müsste. Dort ist die 12.1.1 inkludiert. Es gibt aber schon 13.1.0. Leider weiß ich nicht, wie ich aus der Ring-Client-Api von Github ein Projekt bekomme, dass ich in Iobroker\node_modules\ring-client-api einfügen könnte.

      posted in ioBroker Allgemein
      U
      undeat
    • Wallbox nur über Iob steuern

      Hallo zusammen,

      ich bekomme bald ein e-auto und beschäftige mich nun mit dem Thema Wallboxen. Da ich eine PV-Anlage habe, möchte ich natürlich zuhause das Überschussladen realisieren. Dazu gibt es bereits viele Beiträge aber ich habe noch nicht genau das gefunden, was ich brauche.

      Das Problem bei mir ist, dass ich einen Growatt Wechselrichter habe, von dem ich über Modbus RTU mit einem ModBus Adapter vom Iob Die Werte auslese. Außerdem bekomme ich die Werte vom Hauszähler über einen SmartMeter Adapter im IoBroker. Die Wallbox, ob mit OpenWB oder EECV kann daher nicht direkt mit dem WR oder dem Hauszähler kommunizieren.

      Ich habe im Iob bereits die Daten, wie viel ins Netz eingespeist wird und wie voll eventuell später ein Akku ist usw. Ich möchte daher einfach mit iob in die Wallbox schreiben, mit wie viel Watt diese laden darf. Das würde ich dann alle paar Sekunden, wenn vom SmartMeter neue Werte kommen. Außerdem könnte ich dann auf irgendwelchen wegen auch die Überschussladung deaktivieren und 11kw in die Wallbox schreiben um schnell aus dem Netz zu laden.

      Ich brauche also nur IOB (Max Ladeleistung) -> Wallbox

      Ich habe noch keine Wallbox gekauft. Eventuell wird es der go echarger.

      Ich habe außerdem gesehen, dass open WB und eevc auch eine Anbindung an die API vom Auto bekommen. Wozu brauchen die das?

      posted in ioBroker Allgemein
      U
      undeat
    • RE: NodeRed fkt. nicht nach Node.js Update auf 18.20.2

      @mcm57

      Win11
      Node.js 18.20.2
      node-red Adapter 5.2.0
      NPM 10.5.0

      Node-RED: 20 Apr 18:32:29 - [error] Error: spawn EINVAL at ChildProcess.spawn (node:internal/child_process:414:11) at spawn (node:child_process:761:9) at Object.execFile (node:child_process:351:17) at G:\SmartHome\node_modules@node-red\registry\lib\installer.js:581:27 at new Promise (<anonymous>) at Object.checkPrereq (G:\SmartHome\node_modules@node-red\registry\lib\installer.js:580:16) at Object.load (G:\SmartHome\node_modules@node-red\registry\lib\index.js:59:22) at G:\SmartHome\node_modules@node-red\runtime\lib\index.js:162:29

      Ich habe es selbst hin bekommen.

      Ich habe die node-red 3.1.9.zip herunter geladen und die beiden Ordner, die da drin sind ("node-red" und "@node-red") in den Ordner "G:\SmartHome\node_modules" kopiert. Nun läuft es wieder

      posted in Error/Bug
      U
      undeat
    • RE: NodeRed fkt. nicht nach Node.js Update auf 18.20.2

      @mcm57 Ich habe das gleiche Problem. Der Telegram Adapter und der vom Saugroboter haben mich auf node 18.20 gezwungen aber jetzt geht node red nicht mehr. Der Fix für Node Red sollte ja da sein, aber wie bekomme ich den in das Node Red vom Iobroker? Ein Update für den Adapter gibt es noch nicht, auch nicht als Beta.

      posted in Error/Bug
      U
      undeat
    • RE: Steht offen im Internet ???

      @klassisch Ja so mache ich das jetzt auch, nur dass der IOB von Außen nicht erreichbar ist und ich damit die Simple Api keinen http req bekommen kann wenn ich nicht im Heimischen Netz bin. Daher habe ich eine Webseite mit einem Skript, die das http req lokal im Lan macht erstellt um eben nicht die ganze API von außen zugänglich zu haben.

      posted in ioBroker Allgemein
      U
      undeat
    • RE: Steht offen im Internet ???

      @ahnungsbefreit
      Wie kann man die Simple Api am besten von "außen" ansprechen?

      posted in ioBroker Allgemein
      U
      undeat
    • RE: Steht offen im Internet ???

      @apollon77
      Apache ist ca. ein halbes Jahr alt. Im htdocs war noch das Dashboard drin. Das habe ich erstmal gelöscht, so das nur noch meine Rolltor.php drin ist. Ich habe mal kurz nach dem Eintrag mit dem CONNECT gegoggelt. Das scheint irgendwie eine direkte Verbindung zu dem Http server zu sein. Was auch immer das bedeutet. Das brauche ich ja auch nicht und man müsste es vielleicht nur irgendwo abschalten. Ich lasse Apache jetzt mal noch laufen und habe ein Auge auf die Logs. Auf Dauer werde ich mir das VPN on Demand mal anschauen. Das sieht gut aus.

      Aber trotzdem muss jemand den Apache gehackt haben und dann iob gefunden haben, um dort das Skript anzulegen. Das ist doch mega Unwahrscheinlich. Klar ist iob verbreitet aber das wird ja wohl trotzdem auf deutlich weniger als 1% der Rechner laufen.

      Oder jemand hat etwas Manipuliert, das das iob offen liegt und dann hat es jemand gefunden und das Skript angelegt aber dann ist das Problem jetzt wahrscheinlich noch nicht behoben.

      posted in ioBroker Allgemein
      U
      undeat
    • RE: Steht offen im Internet ???

      @samson71

      @samson71 said in Steht offen im Internet ???:

      @undeat sagte in Steht offen im Internet ???:

      Gibt es hierzu andere Vorschläge?

      Öffnung per Sprache (Alexa) 😊

      Das mache ich schon aber der Alexa Dienst auf meiner Galaxy Watch ist nicht immer zu zuverlässigste.
      Ansonsten kann ich selbstverständlich wie James Bond meiner Uhr sagen, das die Garage geöffnet werden soll 😉

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