Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. Internet Filter in der Fritzbox mit JavaScript setzen

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.6k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.1k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    2.8k

Internet Filter in der Fritzbox mit JavaScript setzen

Geplant Angeheftet Gesperrt Verschoben JavaScript
fritzboxkindersicherungfilter
145 Beiträge 24 Kommentatoren 25.7k Aufrufe 36 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • J Juge

    @moelski Habe quasi nix am Hut mit Jawa - ich bin jetzt auf diese Diskussion gelandet da ich verzweifelt nach dem Filterwechsel gegoogelt habe. Eigentlich würde ich es am liebsten über shell skript steuern.

    Ich habe mein nächstes Projekt auf dem Visier. Ich habe mir Raspi besorgt und wollte pi-hole installieren.
    Aktuell mit dem Homeschooling würde ich gern gewisse Anwendungen restriktieren. Also in der Schoolzeit kein YouTube, Tiktok, Netflix, Prime oder Discord. Pi-hole ist wahrscheinlich nicht die richtige Lösung da man es umgehen kann, aber ich denke es konnte möglich sein sie alle mit fritzbox Zugangsprofile zu sperren (wenn man die IPs rausfindet) Problem ist dass Fritzbox lässt die Profilen nicht zeitlich steuern...komplette Internetzugang sperren ist ausgeschlossen (weil dann können sie auch nicht Teams oder etwas mit Schule machen). Profilwechsel konnte ich von Raspi mit einem cronjob steuern...

    Dein Jawa skript sieht genau nach der richtige Lösung aus. Nur ich fürchte es funktioniert wohl nur mit iobroker oder wie? Ich habe versucht es einfach blanco von Ubuntu mit node filterprofile.js auszuführen und kriege meckere:

    on({id: FbIobObject, change: "ne"}, function (obj) {
    ^
    
    ReferenceError: on is not defined
    
    

    Gibt's eine Möglichkeit das überhaupt so von Command Line ohne iobroker zum Laufen zu bringen?

    moelskiM Offline
    moelskiM Offline
    moelski
    schrieb am zuletzt editiert von
    #132

    @juge
    Moin !
    Ne das geht nicht aus der Command Line. Da fehlen alle Libs von ioBroker ...

    Wenn es dir nur um das Sperren von ein paar Seiten geht dann ist PiHole sicher der effizientere Weg.
    Ich mach das bei meinem Junior auch. Das schöne ist, dass man pro Gerät Sperrungen definieren kann in PiHole.
    Aber das wird hier dann langsam etwas OT vermutlich ...

    Grüße Dominik

    M 1 Antwort Letzte Antwort
    0
    • moelskiM moelski

      @juge
      Moin !
      Ne das geht nicht aus der Command Line. Da fehlen alle Libs von ioBroker ...

      Wenn es dir nur um das Sperren von ein paar Seiten geht dann ist PiHole sicher der effizientere Weg.
      Ich mach das bei meinem Junior auch. Das schöne ist, dass man pro Gerät Sperrungen definieren kann in PiHole.
      Aber das wird hier dann langsam etwas OT vermutlich ...

      M Offline
      M Offline
      mumurik
      schrieb am zuletzt editiert von
      #133

      @moelski

      eine Frage, wäre es möglich mit dem Skript auch die Ticketliste (unter Fritzbox-Internet-Filter-Zugangsprofile) in iobroker zu importieren/auszugeben, so dass die Tickets in einzelne Datenobjekte geschrieben werden könnten?

      b9776f6a-2e26-4837-8a0a-6e862e6f90a9-image.png

      1 Antwort Letzte Antwort
      0
      • moelskiM moelski

        Moin !

        Ich habe vor einigen Tagen hier ein Shell Script gefunden um in der Fritzbox Internet Filter zu setzen ohne sich an der FB-Oberfläche anmelden zu müssen:
        https://community.openhab.org/t/disable-internet-connection-of-specific-echo-device-on-fritz-box-via-script/91374

        Es geht um diese Einstellungen hier:
        Screenshot_2020-08-21_10-04-25.png

        Hintergrund ist, dass ich gerne bei einigen Geräten in unserem Netzwerk das Internet (oder bestimmte Seiten) auf Knopfdruck sperren können möchte. Alle mit Kindern und INet Zugang wissen sicher wieso und warum :-)

        Jedenfalls habe ich das Shell Script als Grundlage genutzt und in JavaScript umgesetzt. Funktioniert inzwischen auch wie gewollt.

        Update
        Das Script findet ihr inzwischen in Post 7 inkl. einer kurzen Anleitung:
        https://forum.iobroker.net/topic/36095/internet-filter-in-der-fritzbox-mit-javascript-setzen/7

        Grüße Dominik

        J Offline
        J Offline
        jonacoor
        schrieb am zuletzt editiert von jonacoor
        #134

        Hallo,
        super Skript, leider bekomme ich es bei mir nicht zum laufen (manuelle Ausführung).
        Bin dazu noch Newbe:

        Datenpunkte angelegt (Fritzbox.0... ging nicht):
        const FbIobObject = "0_userdata.0.ChangeDeviceFilter"
        const FbIobJsonList = "0_userdata.0.DeviceFilterListJson"

        Scheint auch alles durchzuführen:
        ad733980-5136-4737-9972-7ae6fcd9b300-grafik.png

        Am Ende ist der jeweilige Filter aber unverändert.

        Habe schon verschiedene Settings probiert
        const FbDebugging = false;
        const FbListOnly = false/true;
        const FbCreateList = false/true;

        Kann jemand helfen ?

        Danke

        Hannes

        // FB 7490 7.27


        Update 15.10.2021:

        Ich hatte statt der Profile ID den Namen verwendet. Wer lesen kann ist klar im Vorteil.

        Bestätige die Funktion bei Fritzbox 7490 FW 7.28

        F 1 Antwort Letzte Antwort
        0
        • J jonacoor

          Hallo,
          super Skript, leider bekomme ich es bei mir nicht zum laufen (manuelle Ausführung).
          Bin dazu noch Newbe:

          Datenpunkte angelegt (Fritzbox.0... ging nicht):
          const FbIobObject = "0_userdata.0.ChangeDeviceFilter"
          const FbIobJsonList = "0_userdata.0.DeviceFilterListJson"

          Scheint auch alles durchzuführen:
          ad733980-5136-4737-9972-7ae6fcd9b300-grafik.png

          Am Ende ist der jeweilige Filter aber unverändert.

          Habe schon verschiedene Settings probiert
          const FbDebugging = false;
          const FbListOnly = false/true;
          const FbCreateList = false/true;

          Kann jemand helfen ?

          Danke

          Hannes

          // FB 7490 7.27


          Update 15.10.2021:

          Ich hatte statt der Profile ID den Namen verwendet. Wer lesen kann ist klar im Vorteil.

          Bestätige die Funktion bei Fritzbox 7490 FW 7.28

          F Offline
          F Offline
          Freaknet
          schrieb am zuletzt editiert von Freaknet
          #135

          @moelski

          Hey,
          ich habe seit dem FW Update meiner FB 7590 das Problem, dass mir keine Device mehr angezeigt werden.
          Hat sich irgendetwas in der FB-Einstellungen geändert?
          Bekomme auch keine SID mehr zugeordnet.

          Hier mal das Log bei Static-Version:

          10:17:48.213	info	javascript.0 (22888) Stop script script.js.Meine_Scripte.Internetzugang
          10:17:48.308	info	javascript.0 (22888) Start javascript script.js.Meine_Scripte.Internetzugang
          10:17:48.310	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: Profile Changer started ... (Version : 1.09)
          10:17:48.310	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: function getFbChallenge
          10:17:48.311	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: Profile Changer done
          10:17:48.311	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: registered 0 subscriptions and 0 schedules
          10:17:48.691	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Challenge : f4d35392
          10:17:48.691	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > MD5 : 278c6355de6b1ca2c16cc08c02ff4e0a
          10:17:48.692	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Login : response=f4d35392-278c6355de6b1ca2c16cc08c02ff4e0a&username=
          10:17:48.692	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: function getFbSid
          10:17:49.767	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > SID : 0000000000000000
          10:17:49.768	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: function getFbProfiles
          10:17:50.012	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Decode Names
          10:17:50.014	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Decode Filters
          10:17:50.014	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: Filter Count : 0
          10:17:50.014	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: function getFbDevices
          10:17:50.207	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Decode Device Names
          10:17:50.207	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Decode Device Ids
          10:17:50.208	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: Device Count : 0
          10:17:50.208	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: DONE : Listmode - No Device blocking ...
          

          An den Einstellungen am Script habe ich seit über 1 Jahr nichts mehr geändert.

          // Die IP Der Fritzbox
          const FbIp          = "192.168.178.1";              
          // Der User der Fritzbox 
          // HINWEIS : Den Benutzer leer lassen wenn die Anmeldung an der FB nur mit Passwort erfolgt !
          const FbUser        = ""; 
          // Das Password der Fritzbox                  
          const FbPassword    = "**********";   
          // welcher Rechner soll "bearbeitet" werden                
          var   FbDevice      = "Comp-L-Pi";   
          // Das neue Profil für den Rechner              
          var   FbProfile     = "filtprof4";  
          // erweitertes Logging aktivieren für Fehlersuche
          const FbDebugging   = false;
          // Keine Änderung an der Fritzbox (true) -> Listet dann nur alle Profile und Rechner               
          const FbListOnly    = true; 
          // Device / Filter Liste erzeugen Ja (true), Nein (false)
          const FbCreateList  = true; 
          // Datenpunkt (string) für einen automatischen Script Start (muss angelegt werden!)
          // Der Datenpunkt wir mit Device;Profil beschrieben. Bsp: Comp-L-Pi;filtprof1
          const FbIobObject   = "0_userdata.0.Fritzbox.ChangeDeviceFilter"  
          // Datenpunkt in den die Device / Filter Liste als JSON geschrieben wird                    
          const FbIobJsonList = "0_userdata.0.Fritzbox.DeviceFilterListJson"
          

          Hat jemand ein ähnliches Problem seit dem FW-Update?

          Grüße
          Freaknet

          P.S.: Hat sich erledigt... Hab einfach einen Benutzer angelegt in der FB und schon läuft die Sache wieder ;-)

          ? 1 Antwort Letzte Antwort
          0
          • F Freaknet

            @moelski

            Hey,
            ich habe seit dem FW Update meiner FB 7590 das Problem, dass mir keine Device mehr angezeigt werden.
            Hat sich irgendetwas in der FB-Einstellungen geändert?
            Bekomme auch keine SID mehr zugeordnet.

            Hier mal das Log bei Static-Version:

            10:17:48.213	info	javascript.0 (22888) Stop script script.js.Meine_Scripte.Internetzugang
            10:17:48.308	info	javascript.0 (22888) Start javascript script.js.Meine_Scripte.Internetzugang
            10:17:48.310	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: Profile Changer started ... (Version : 1.09)
            10:17:48.310	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: function getFbChallenge
            10:17:48.311	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: Profile Changer done
            10:17:48.311	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: registered 0 subscriptions and 0 schedules
            10:17:48.691	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Challenge : f4d35392
            10:17:48.691	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > MD5 : 278c6355de6b1ca2c16cc08c02ff4e0a
            10:17:48.692	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Login : response=f4d35392-278c6355de6b1ca2c16cc08c02ff4e0a&username=
            10:17:48.692	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: function getFbSid
            10:17:49.767	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > SID : 0000000000000000
            10:17:49.768	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: function getFbProfiles
            10:17:50.012	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Decode Names
            10:17:50.014	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Decode Filters
            10:17:50.014	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: Filter Count : 0
            10:17:50.014	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: function getFbDevices
            10:17:50.207	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Decode Device Names
            10:17:50.207	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: > Decode Device Ids
            10:17:50.208	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: Device Count : 0
            10:17:50.208	info	javascript.0 (22888) script.js.Meine_Scripte.Internetzugang: DONE : Listmode - No Device blocking ...
            

            An den Einstellungen am Script habe ich seit über 1 Jahr nichts mehr geändert.

            // Die IP Der Fritzbox
            const FbIp          = "192.168.178.1";              
            // Der User der Fritzbox 
            // HINWEIS : Den Benutzer leer lassen wenn die Anmeldung an der FB nur mit Passwort erfolgt !
            const FbUser        = ""; 
            // Das Password der Fritzbox                  
            const FbPassword    = "**********";   
            // welcher Rechner soll "bearbeitet" werden                
            var   FbDevice      = "Comp-L-Pi";   
            // Das neue Profil für den Rechner              
            var   FbProfile     = "filtprof4";  
            // erweitertes Logging aktivieren für Fehlersuche
            const FbDebugging   = false;
            // Keine Änderung an der Fritzbox (true) -> Listet dann nur alle Profile und Rechner               
            const FbListOnly    = true; 
            // Device / Filter Liste erzeugen Ja (true), Nein (false)
            const FbCreateList  = true; 
            // Datenpunkt (string) für einen automatischen Script Start (muss angelegt werden!)
            // Der Datenpunkt wir mit Device;Profil beschrieben. Bsp: Comp-L-Pi;filtprof1
            const FbIobObject   = "0_userdata.0.Fritzbox.ChangeDeviceFilter"  
            // Datenpunkt in den die Device / Filter Liste als JSON geschrieben wird                    
            const FbIobJsonList = "0_userdata.0.Fritzbox.DeviceFilterListJson"
            

            Hat jemand ein ähnliches Problem seit dem FW-Update?

            Grüße
            Freaknet

            P.S.: Hat sich erledigt... Hab einfach einen Benutzer angelegt in der FB und schon läuft die Sache wieder ;-)

            ? Offline
            ? Offline
            Ein ehemaliger Benutzer
            schrieb am zuletzt editiert von
            #136

            @freaknet genau, der Username ist Pflicht geworden.. das wars.. :-)

            1 Antwort Letzte Antwort
            1
            • T Offline
              T Offline
              Torsten_MG
              schrieb am zuletzt editiert von Torsten_MG
              #137

              Hallo, ich nutze das Script schon länger, nun ist mir aufgefallen das der Filter nicht mehr die Richtigen Geräte ändert.

              Ich habe z.B. folgende Geräte in der Fritzbox

              Ben-Handy
              Ben-CT

              LAPTOP-Ben
              Mini-PC-Ben

              Wenn ich jetzt z.B. in "0_userdata.0.Fritzbox.ChangeDeviceFilter"

              "Ben-Handy;filtprof880" eingebe, wird der Filter von "Ben-CT" geändert

              und bei "LAPTOP-Ben;filtprof880" wird der Filter von "Mini-PC-Ben" geändert.

              Seit wann das so ist, weiss ich leider nicht, ist mir gestern aufgefallen, weil Junior um 21:45Uhr noch am Laptop saß

              Das kann ich so weiterführen, ist bei anderen Geräten genauso :confused:

              EDIT sagt:

              Ich habe gerade mal einige "Leichen" in der Fritzbox unter Heimnetz > Netzwerk > Netzwerkverbindungen gelöscht und den Eintrag bei 0_userdata.0.Fritzbox.DeviceFilterListJson gelöscht, steht also nichts mehr drin.

              Scheint jetzt wieder zu funktionieren

              1 Antwort Letzte Antwort
              0
              • A Offline
                A Offline
                amandus99
                schrieb am zuletzt editiert von
                #138

                erstmal Danke fürs Script. Läuft wunderbar und ich kann nun über mein node-red dashboard eine Camera das selbst erstellte Profil "blocked" zuweisen und auch wieder auf Standard stellen. Die Idee ist der Camera nur Internet zur Verfügung zu stellen wenn ich das auch explizit will. Ansonsten soll die Kamera nur im eigenen Netz erreichbar sein. Über das Schalten auf dem Dashboard wird das Profil auch sauber zugewiesen, ABER das Profil hat scheinbar überhaupt keine Wirkung! Das Profil "blocked" hat laut Configseite als onlineZeit "keine". Aber wie gesagt die Kamera ist trotzdem übers Handy ohne WLAN aktiviert erreichbar.

                1 Antwort Letzte Antwort
                0
                • moelskiM moelski

                  Moin !

                  Gestern Abend doch glatt am TV verschlummert :face_with_rolling_eyes: Aber nun ...

                  Hier aber nun das Script:

                  /*******************************************************
                  * Basis: 
                  * https://community.openhab.org/t/disable-internet-connection-of-specific-echo-device-on-fritz-box-via-script/91374
                  * https://forum.fhem.de/index.php?topic=109689.0
                  * https://www.kuketz-blog.de/fritzbox-wlan-toggle-per-skript/
                  *******************************************************/ 
                  
                  /*******************************************************
                  * Script SetDeviceFilter
                  * 
                  * 13.09.20 V1.09    Regex mit Escape beim . und Fix für Liste
                  * 12.09.20 V1.08    Regex um . erweitert
                  * 12.09.20 V1.07    Erweritertes Logging aktivierbar für Fehlersuche
                  * 08.09.20 V1.06    Anpassungen an FirtzOS 7.20 (Regex Auswertung für Listenerstellung)
                  * 05.09.20 V1.05    Ausgabe einer Device / Filter Liste möglich als JSON 
                  *                   Logging reduziert wenn FbListOnly = false
                  * 04.09.20 V1.04    Fix für doppelte Einträge in Listen
                  * 02.09.20 V1.03    Erweiterung zum automatischen Start mittels ioB Datenpunkt
                  * 02.09.20 V1.02    Script Abbruch wenn der Login nicht geklappt hat
                  * 02.09.20 V1.01    Regex Erweiterung, Login auch mit User/Passwort
                  * 01.09.20 V1.00    erste öffentliches Release
                  *******************************************************/ 
                  const Version = "1.09";
                  
                  // TODO
                  // * Liste erzeugen mit Devices und aktuellem Filter
                  //   > als JSON in einen DP speichern -> für Tabellenauswertung
                  
                  // https://forum.iobroker.net/topic/16184/http-request-in-javascript/5
                  var request = require('request');
                  var headers = { 
                      'Content-Type': 'application/x-www-form-urlencoded', 
                      'User-Agent': 'curl/7.64.0', 
                      'Accept': '*/*'
                  }; 
                  
                  /*******************************************************
                  * E I N S T E L L U N G E N 
                  *******************************************************/
                  
                  // Die IP Der Fritzbox
                  const FbIp          = "192.168.30.1";              
                  // Der User der Fritzbox 
                  // HINWEIS : Den Benutzer leer lassen wenn die Anmeldung an der FB nur mit Passwort erfolgt !
                  const FbUser        = ""; 
                  // Das Password der Fritzbox                  
                  const FbPassword    = "";   
                  // welcher Rechner soll "bearbeitet" werden                
                  var   FbDevice      = "Comp-L-Pi";   
                  // Das neue Profil für den Rechner              
                  var   FbProfile     = "filtprof4";  
                  // erweitertes Logging aktivieren für Fehlersuche
                  const FbDebugging   = false;
                  // Keine Änderung an der Fritzbox (true) -> Listet dann nur alle Profile und Rechner               
                  const FbListOnly    = false; 
                  // Device / Filter Liste erzeugen Ja (true), Nein (false)
                  const FbCreateList  = true; 
                  // Datenpunkt (string) für einen automatischen Script Start (muss angelegt werden!)
                  // Der Datenpunkt wir mit Device;Profil beschrieben. Bsp: Comp-L-Pi;filtprof1
                  const FbIobObject   = "Global.0.Fritzbox.ChangeDeviceFilter"  
                  // Datenpunkt in den die Device / Filter Liste als JSON geschrieben wird                    
                  const FbIobJsonList = "Global.0.Fritzbox.DeviceFilterListJson" 
                  
                  var secChallenge;
                  var secMd5;
                  var secLogin;
                  var secSid;
                  var secProfileNames = [];
                  var secProfileIds   = [];
                  var secDeviceNames  = [];
                  var secDeviceIds    = [];
                  var JsonList        = "";
                  
                  /*******************************************************
                  * Object Trigger Version
                  * Wenn auf einen Datenpunkt getriggert werden soll, dann muss der folgende Block auskommentiert werden. 
                  * FbIobObject muss mit einem string Datenpunkt versehen werden.
                  * Den Static Teil dann auskommentieren !
                  * Diese Variante erlaubt es das Script dynamisch für alle Devices / Profile der FB zu verwenden. 
                  *******************************************************/
                  on({id: FbIobObject, change: "ne"}, function (obj) {
                      console.log("Profile Changer started ... (Version : " + Version + ")");
                      var data = obj.state.val.split(";");
                      if (data.length != 2) {
                          console.log("Wrong parameter : " + obj.state.val);
                          return;
                      }
                  
                      if (FbDebugging){
                          console.log(" > Datapoint : " + data);
                      }
                  
                      console.log("Computer : " + data[0]);
                      console.log("Filter   : " + data[1]);
                      FbDevice  = data[0];
                      FbProfile = data[1];
                  
                      getFbChallenge();
                      
                      console.log("Profile Changer done");
                  });
                  
                  /*******************************************************
                  * Static Version
                  * Die folgenden 3 Zeilen lassen das Script  sofort laufen. 
                  * Dabei sollte der Object Trigger Block auskommentiert werden. 
                  *******************************************************/
                  // console.log("Profile Changer started ... (Version : " + Version + ")");
                  // getFbChallenge();
                  // console.log("Profile Changer done");
                  
                  // Get the Challenge String from the FritzBox
                  // Compute the md5 Hash
                  function getFbChallenge(){
                      console.log("function getFbChallenge");
                      request.get({
                          url:        'http://' + FbIp + '/login_sid.lua?username=' + FbUser,
                          headers:    headers
                      }, function(error, response, body) {
                          if (error) log(error, 'error');
                          //console.log(response);
                          // 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
                          secChallenge = body.match(/Challenge>(.*)<\/Challenge/)[1];
                          console.log(" > Challenge : " + secChallenge);
                  
                          var uft16le = str2rstr_utf16le(secChallenge + "-" +FbPassword );
                          var md5     = rstr_md5(uft16le);
                          secMd5      = rstr2hex(md5);
                                  
                          console.log(" > MD5       : " + 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)
                          secLogin = "response=" + secChallenge + "-" + secMd5 + "&username=" + FbUser;
                  
                          console.log(" > Login     : " + secLogin);
                  
                          getFbSid();
                      });
                  }
                  
                  // Get the SID from the Fritzbox
                  function getFbSid() {
                      console.log("function getFbSid");
                  
                      request.post({
                          url:        'http://' + FbIp,
                          headers:    headers, 
                          form:       secLogin
                      }, function(error, response, body) {
                          if (error) log(error, 'error');
                          // SID filtern 
                          // "sid":"c503b24dae458086"
                          try {
                              secSid = response.body.match(/\"sid\":\"(.*)\"/)[1];
                          }
                          catch (e) {
                              if (secSid == undefined) {
                                  console.log("Your login was not successful. End Script", Error)
                                  return;
                              }
                          }
                  
                          console.log(" > SID       : " + secSid);
                  
                          //getFbDeviceInfos();
                          getFbProfiles();
                      });
                  } 
                  
                  // TBD: 
                  // Netzwerkinfos mit allen Devices lesen: 
                  // var req = "xhr=1&sid=" + secSid + "&lang=de&page=netDev&xhrId=cleanup&useajax=1&no_sidrenew=" 
                  function getFbDeviceInfos(){
                      console.log("function getFbDeviceInfos");
                      var req = "xhr=1&sid=" + secSid + "&lang=de&page=netDev&xhrId=cleanup&useajax=1&no_sidrenew=" 
                  
                      request.post({
                          url:        'http://' + FbIp + '/data.lua',
                          headers:    headers, 
                          form:       req
                      }, function(error, response, body) {
                          if (error) log(error, 'error');
                          console.log(response.body);
                      });    
                  }
                  
                  // Get all Profiles from the Fritzbox
                  function getFbProfiles() {
                      console.log("function getFbProfiles");
                      // #curl -d "xhr=1&sid=${sid}&lang=de&no_sidrenew=&page=kidPro" "http://$1/data.lua"
                      var req = "xhr=1&sid=" + secSid + "&lang=de&no_sidrenew=&page=kidPro";
                  
                      request.post({
                          url:        'http://' + FbIp + '/data.lua',
                          headers:    headers, 
                          form:       req
                      }, function(error, response, body) {
                          if (error) log(error, 'error');
                          
                          if (FbDebugging){
                              console.log(" > response.body : \n" + response.body);
                          }
                  
                          secProfileIds   = [];
                          secProfileNames = [];
                  
                          console.log(" > Decode Names")
                          var rx = new RegExp( /class=\"name\"\stitle=\"([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"\sdatalabel/g );
                          while( (match = rx.exec( body )) != null ) {
                              secProfileNames.push(match[1]);
                          }
                          if (FbDebugging){
                              console.log(" > secProfileNames : \n" + secProfileNames);
                          }
                  
                          console.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( body )) != null ) {
                              secProfileIds.push(match[1]);
                          }
                          if (FbDebugging){
                              console.log(" > secProfileIds : \n" + secProfileIds);
                          }
                  
                          if (FbListOnly) {
                              console.log("Filter Count : " + secProfileIds.length);
                              for (var i = 0; i < secProfileIds.length; i++) {
                                  console.log("Filter named '"+ secProfileNames[i] + "' has ID : " + secProfileIds[i]);
                              }
                          }
                  
                          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"
                  function getFbDevices() {
                      console.log("function getFbDevices");
                      // xhr=1&sid=5f5ba302815594d8&lang=de&no_sidrenew=&page=kidLis
                      var req = "xhr=1&sid=" + secSid + "&lang=de&no_sidrenew=&page=kidLis";
                  
                      request.post({
                          url:        'http://' + FbIp + '/data.lua',
                          headers:    headers, 
                          form:       req
                      }, function(error, response, body) {
                          if (error) log(error, 'error');
                          if (FbDebugging){
                              console.log(" > response.body : \n" + response.body);
                          }
                  
                          // TESTING
                          //body = getState("Global.0.Testing.StringValue").val;
                  
                          secDeviceNames = [];
                          secDeviceIds   = [];
                  
                          console.log(" > Decode Device Names")
                          var rx = new RegExp( /class=\"name"\stitle=\"([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"\sdatalabel/g );
                          while( (match = rx.exec( body )) != null ) {
                              secDeviceNames.push(match[1]);
                          }
                          if (FbDebugging){
                              console.log(" > secDeviceNames : \n" + secDeviceNames);
                          }
                  
                          console.log(" > Decode Device Ids")
                          rx = new RegExp( /name=\"profile:([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"><option/g );
                          while( (match = rx.exec( body )) != null ) {
                              secDeviceIds.push(match[1]);
                          }
                          if (FbDebugging){
                              console.log(" > secDeviceIds : \n" + secDeviceIds);
                          }
                          
                          if (FbListOnly) {
                              console.log("Device Count : " + secDeviceIds.length);
                              for (var i = 0; i < secDeviceNames.length; i++) {
                                  console.log(i + " - Device named '"+ secDeviceNames[i] + "' has ID : " + secDeviceIds[i]);
                              }
                          }
                  
                          if (!FbListOnly) { 
                              setFbSperre(); 
                          } else { 
                              console.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
                  function setFbSperre() {
                      console.log("function setFbSperre");
                      
                      // Device suchen ... 
                      var devId = -1;
                      for (var i = 0; i < secDeviceNames.length; i++) {
                          if (secDeviceNames[i] == FbDevice) {
                              devId = i;
                          }
                      }
                      
                      console.log(" > Device Nr   : " + devId); 
                      console.log(" > Device ID   : " + secDeviceIds[devId]); 
                      console.log(" > Device Name : " + 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=" + secSid + "&lang=de&no_sidrenew=&profile%3A" + secDeviceIds[devId] + "=" + FbProfile + "&apply=&oldpage=%2Finternet%2Fkids_userlist.lua";
                      console.log(" > req : " + req2);
                      //var req2 = "xhr=1&sid=" + sid + "&lang=de&no_sidrenew=&profile%3Alandevice308962=filtprof3079&profile%3Auser7725=filtprof4&profile%3Alandevice2671=filtprof1&profile%3Alandevice2444=filtprof1&profile%3Alandevice2330=filtprof1&profile%3Alandevice2195=filtprof1&profile%3Alandevice229903=filtprof1&profile%3Alandevice8486=filtprof1&profile%3Alandevice1908=filtprof1&profile%3Alandevice1865=filtprof1&profile%3Alandevice516865=filtprof1&profile%3Alandevice518551=filtprof1&profile%3Alandevice169594=filtprof1&profile%3Alandevice171398=filtprof1&profile%3Alandevice175510=filtprof1&profile%3Alandevice177635=filtprof1&profile%3Alandevice178875=filtprof1&profile%3Alandevice179702=filtprof1&profile%3Alandevice180995=filtprof1&profile%3Alandevice182196=filtprof1&profile%3Alandevice183607=filtprof1&profile%3Alandevice184405=filtprof1&profile%3Alandevice638220=filtprof1&profile%3Alandevice634583=filtprof1&profile%3Alandevice7650=filtprof1&profile%3Alandevice353720=filtprof1&profile%3Auser7731=filtprof4&profile%3Alandevice170191=filtprof1&profile%3Alandevice941076=filtprof1&profile%3Alandevice358722=filtprof1&profile%3Alandevice2859=filtprof1&profile%3Auser7739=filtprof4&profile%3Alandevice8035=filtprof1&profile%3Auser7733=filtprof4&profile%3Auser7740=filtprof4&profile%3Alandevice1333=filtprof1&profile%3Alandevice6211=filtprof1&profile%3Alandevice35977=filtprof1&profile%3Alandevice8101=filtprof1&profile%3Alandevice8174=filtprof1&profile%3Auser7729=filtprof4&profile%3Alandevice1125=filtprof1&profile%3Alandevice1124=filtprof1&profile%3Alandevice7715=filtprof1&profile%3Alandevice52361=filtprof1&profile%3Alandevice30084=filtprof1&profile%3Alandevice26151=filtprof1&profile%3Alandevice26138=filtprof1&profile%3Alandevice6162=filtprof1&profile%3Alandevice5204=filtprof1&profile%3Alandevice1129367=filtprof1&profile%3Alandevice9399=filtprof1&profile%3Alandevice232149=filtprof1&profile%3Alandevice6935=filtprof1&profile%3Alandevice941333=filtprof1&profile%3Alandevice941569=filtprof1&apply=&oldpage=%2Finternet%2Fkids_userlist.lua";
                      //var req2 = "xhr=1&sid=" + sid + "&lang=de&no_sidrenew=&profile:landevice308962=filtprof4&apply=&oldpage=/internet/kids_userlist.lua";
                  
                      request.post({
                          url:        'http://' + FbIp + '/data.lua',
                          headers:    headers, 
                          form:       req2
                      }, function(error, response, body) {
                          if (error) log(error, 'error');
                          if (FbDebugging){
                              console.log(" > response : \n" + response);
                          }
                  
                          console.log("Change done. Check your FB / Device if it worked :-)");
                  
                          if (FbCreateList) {
                              getFbDeviceFilterList();
                          }
                      });    
                  }
                  
                  function getFbDeviceFilterList() {
                      console.log("function getFbDeviceFilterList");
                      
                      // xhr=1&sid=e2d99419592fb780&lang=de&no_sidrenew=&page=kidLis
                      var req = "xhr=1&sid=" + secSid + "&lang=de&no_sidrenew=&page=kidLis";
                  
                      request.post({
                          url:        'http://' + FbIp + '/data.lua',
                          headers:    headers, 
                          form:       req
                      }, function(error, response, body) {
                          //if (error) log(error, 'error');
                          //console.log(response.body);
                  
                          JsonList = "";
                          var tmpDevices      = [];
                          var tmpUsage        = [];
                          var tmpProfilesId   = [];
                          var tmpProfilesName = [];
                          var tmpTimes        = [];
                  
                          // TESTING
                          //body = getState("Global.0.Testing.StringValue").val;
                          
                          console.log(" > Decode Device Names")
                          var rx = new RegExp(/class=\"name"\stitle=\"([a-zA-Z0-9 äöüÄÖÜ\-\_\.]*)\"\sdatalabel/g);
                          while ((match = rx.exec(body)) != null) {
                              tmpDevices.push(match[1]);
                          }
                          //console.log(" > " + tmpDevices);
                  
                          console.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(body)) != null) {
                              tmpProfilesId.push(match[1]);
                          }
                          //console.log(" > " + tmpProfilesId);
                  
                          console.log(" > Decode Device Profile Names");
                          for (var i = 0; i < tmpProfilesId.length; i++) {
                              for (var j = 0; j < secProfileIds.length; j++) { 
                                  //console.log(tmpProfilesId[i] + " > " + secProfileIds[j]);
                                  if (tmpProfilesId[i] == secProfileIds[j]){
                                      tmpProfilesName.push(secProfileNames[j]);
                                  }
                              }
                          }
                          //console.log(" > " + tmpProfilesName);
                  
                          console.log(" > Decode Internetnutzung")
                          rx = new RegExp(/td\sdatalabel=\"[a-zA-Z0-9 äöüÄÖÜ\-]+\"\sclass=\"usage\">(.*?)<\/td>/g);
                          while ((match = rx.exec(body)) != null) { 
                              var tmp = match[1];
                              tmp = tmp.replace("<span>", "").replace("<\/span>", "");
                              tmpUsage.push(tmp);
                          }
                          //console.log(" > " + tmpUsage);
                  
                          console.log(" > Decode Times")
                          rx = new RegExp(/td\sdatalabel=\"[a-zA-Z0-9 äöüÄÖÜ\-]+\"\sclass=\"bar\stime\">(.*?)<\/td>/g);
                          while ((match = rx.exec(body)) != 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);
                              }
                          }
                          //console.log(" > " + tmpTimes);
                  
                          // console.log("Device Count : " + secDeviceIds.length);
                          JsonList = "[";
                          for (var i = 0; i < tmpDevices.length; i++) {
                              JsonList += "{";
                              JsonList += "\"Device\": \"" + tmpDevices[i] + "\"," 
                              JsonList += "\"Profile ID\": \"" + tmpProfilesId[i] + "\","
                              JsonList += "\"Profile Name\": \"" + tmpProfilesName[i] + "\","
                              JsonList += "\"Usage\": \"" + tmpUsage[i] + "\","
                              JsonList += "\"Time\": \"" + tmpTimes[i] + "\""
                              if (i != tmpDevices.length - 1) { JsonList += "},"; } else { JsonList += "}"; }
                          }
                          JsonList += "]";
                  
                          //console.log(JsonList);
                          setState(FbIobJsonList,  JsonList, true);
                  
                          console.log("DONE : List generated ...");
                      });   
                  }
                  
                  
                  // https://gist.githubusercontent.com/josedaniel/951664/raw/33c7a6b44d6cc53dc75cb5230fb551bc4ba7a46a/md5.js
                  // http://pajhome.org.uk/crypt/md5/instructions.html
                  
                  /*
                   * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
                   * Digest Algorithm, as defined in RFC 1321.
                   * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
                   * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
                   * Distributed under the BSD License
                   * See http://pajhome.org.uk/crypt/md5 for more info.
                   */
                  
                  /*
                   * Configurable variables. You may need to tweak these to be compatible with
                   * the server-side, but the defaults work in most cases.
                   */
                  var hexcase = 0;   /* hex output format. 0 - lowercase; 1 - uppercase        */
                  var b64pad  = "";  /* base-64 pad character. "=" for strict RFC compliance   */
                  
                  /*
                   * These are the functions you'll usually want to call
                   * They take string arguments and return either hex or base-64 encoded strings
                   */
                  function hex_md5(s)    { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
                  function b64_md5(s)    { return rstr2b64(rstr_md5(str2rstr_utf8(s))); }
                  function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); }
                  function hex_hmac_md5(k, d)
                    { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
                  function b64_hmac_md5(k, d)
                    { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
                  function any_hmac_md5(k, d, e)
                    { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
                  
                  /*
                   * Perform a simple self-test to see if the VM is working
                   */
                  function md5_vm_test()
                  {
                    return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72";
                  }
                  
                  /*
                   * Calculate the MD5 of a raw string
                   */
                  function rstr_md5(s)
                  {
                    return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
                  }
                  
                  /*
                   * Calculate the HMAC-MD5, of a key and some data (raw strings)
                   */
                  function rstr_hmac_md5(key, data)
                  {
                    var bkey = rstr2binl(key);
                    if(bkey.length > 16) bkey = 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 = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
                    return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
                  }
                  
                  /*
                   * Convert a raw string to a hex string
                   */
                  function rstr2hex(input)
                  {
                    try { hexcase } catch(e) { hexcase=0; }
                    var hex_tab = 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
                   */
                  function rstr2b64(input)
                  {
                    try { b64pad } catch(e) { 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 += b64pad;
                        else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
                      }
                    }
                    return output;
                  }
                  
                  /*
                   * Convert a raw string to an arbitrary string encoding
                   */
                  function 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.
                   */
                  function 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;
                  }
                  
                  /*
                   * Encode a string as utf-16
                   */
                  function 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;
                  }
                  
                  function 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;
                  }
                  
                  /*
                   * Convert a raw string to an array of little-endian words
                   * Characters >255 have their high-byte silently ignored.
                   */
                  function 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
                   */
                  function 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.
                   */
                  function 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 = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
                      d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
                      c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
                      b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
                      a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
                      d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
                      c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
                      b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
                      a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
                      d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
                      c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
                      b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
                      a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
                      d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
                      c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
                      b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
                  
                      a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
                      d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
                      c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
                      b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
                      a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
                      d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
                      c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
                      b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
                      a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
                      d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
                      c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
                      b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
                      a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
                      d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
                      c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
                      b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
                  
                      a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
                      d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
                      c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
                      b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
                      a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
                      d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
                      c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
                      b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
                      a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
                      d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
                      c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
                      b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
                      a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
                      d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
                      c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
                      b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
                  
                      a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
                      d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
                      c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
                      b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
                      a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
                      d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
                      c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
                      b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
                      a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
                      d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
                      c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
                      b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
                      a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
                      d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
                      c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
                      b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
                  
                      a = safe_add(a, olda);
                      b = safe_add(b, oldb);
                      c = safe_add(c, oldc);
                      d = safe_add(d, oldd);
                    }
                    return Array(a, b, c, d);
                  }
                  
                  /*
                   * These functions implement the four basic operations the algorithm uses.
                   */
                  function md5_cmn(q, a, b, x, s, t)
                  {
                    return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
                  }
                  function md5_ff(a, b, c, d, x, s, t)
                  {
                    return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
                  }
                  function md5_gg(a, b, c, d, x, s, t)
                  {
                    return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
                  }
                  function md5_hh(a, b, c, d, x, s, t)
                  {
                    return md5_cmn(b ^ c ^ d, a, b, x, s, t);
                  }
                  function md5_ii(a, b, c, d, x, s, t)
                  {
                    return 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.
                   */
                  function 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.
                   */
                  function bit_rol(num, cnt)
                  {
                    return (num << cnt) | (num >>> (32 - cnt));
                  }
                  

                  Ursprung
                  Das Script basiert auf einem Post den ich mal gefunden habe und zwar hier:
                  https://community.openhab.org/t/disable-internet-connection-of-specific-echo-device-on-fritz-box-via-script/91374
                  Das ist nur ein 5 Zeilen Shell Script und ich habe mir gedacht dass das auch in JavaScript gehen müsste - tut es auch :-)

                  Funktionsweise
                  Das Script läuft in mehreren Stufen ab ... Erst muss eine "Challange" von der FB abgeholt werden. Damit wird dann zusammen mit dem Passwort ein MD5 Hash gebildet.
                  Das nutzt man dann wiederum um die SID von der Fritzbox zu bekommen. Jetzt kann man mit der SID diverse Anfragen an die FB stellen.
                  Ich lese dann z.B. alle verfügbaren Filter Profile aus und die bekannten Geräte in der Fritzbox nebst ihren IDs.
                  Dieser Part ist in dem ursprünglichen Script etwas rudimentär. Da geht es dann mit F12 und Developer Tools ans eingemachte. Aber das lasse ich hier erstmal weg.
                  Am Ende ruft das Script dann eine Seite der FB auf und setzt damit dann den neuen Filter für das Device.

                  Ich sage es mal gleich vorweg ... Die ist keine FB API ! Im Grunde ist es ein Hack der den Login und die Datenbewegung der FB Webseite nutzt - nur eben ohne die Webseite.
                  Und ja ... Man kann mit diesem "Toolset" noch mehr anstellen. Ich kann z.B. alle Geräte der FB lesen mit ihren IPs. Im Grunde muss man über die Developer Tools nur mal schauen was die Webseite so an Daten schiebt wenn man etwas einstellt.
                  Daraus kann man dann interessante Rückschlüsse ziehen. Aber das ist out of Scope hier ...

                  Einrichtung und Nutzung
                  Tja ihr müsst das Script kopieren und im JavaScript Adapter ein neues JavaScript erstellen. Da dann den Inhalt rein kopieren. 90% erledigt :-)
                  Jetzt etwas "Schnüffeln" und Settings setzen.

                  • Zum Testen solltet ihr erstmal die "Static Version" nutzen. Damit läuft das Script nur 1x durch. Wie man das aktiviert steht im Script. Wenn das Script dann sauber läuft kann man auf die "Object Trigger Version" umschwenken und alles über einen Datenpunkt in ioB steuern. Infos dazu stehen im Script.
                  • Erstmal müsst ihr natürlich bei FbIp und FbPassword die entsprechenden Werte eintragen. Also einmal die FB IP und das FB Passwort.
                  • Wenn der Login auf eure FritzBox mittels User und Passwort erfolgt, dann muss in FbUser der User noch eingetragen werden. Ansonsten dieses Feld einfach leer lassen.
                  • FbListOnly jetzt auf true setzen. Denn wir wollen erstmal nur sehen ob es a) klappt und b) die Filter und Devices listen.
                  • Wenn alles eingetragen ist (FbDevice & FbProfile sind an dieser Stelle noch unwichtig) dann mal das Script abspulen lassen ...
                  • Ihr bekommt jetzt im Logging diverse Ausgaben (hoffentlich keine Fehler). Einmal folgendes:
                  06:29:58.055	info	javascript.0 (20276) script.js.Fritzbox.CurlTestFB: > Decode Filters
                  06:29:58.056	info	javascript.0 (20276) script.js.Fritzbox.CurlTestFB: Filter named 'Standard' has ID : filtprof1
                  06:29:58.057	info	javascript.0 (20276) script.js.Fritzbox.CurlTestFB: Filter named 'Gast' has ID : filtprof2
                  06:29:58.057	info	javascript.0 (20276) script.js.Fritzbox.CurlTestFB: Filter named 'Unbeschränkt' has ID : filtprof3
                  06:29:58.057	info	javascript.0 (20276) script.js.Fritzbox.CurlTestFB: Filter named 'Gesperrt' has ID : filtprof4
                  

                  Und dann noch sowas:

                  06:30:01.191	info	javascript.0 (20276) script.js.Fritzbox.CurlTestFB: Device named 'Comp-L-Acer-L' has ID : user2482
                  06:30:01.191	info	javascript.0 (20276) script.js.Fritzbox.CurlTestFB: Device named 'Comp-L-Pi' has ID : landevice37174
                  06:30:01.192	info	javascript.0 (20276) script.js.Fritzbox.CurlTestFB: Device named 'Comp-M-Tablet-W' has ID : landevice2671
                  

                  Wenn das gelistet wird dann funktioniert def. schon mal der Zugriff auf die FB. Wenn nicht ... Nun dann müssen wir mal guggn :-)

                  • Was wir jetzt brauchen ist erstmal das Gerät was wir einstellen wollen. Ihr nehmt also aus der Device Liste die ID.
                    Beispiel:
                    Device named 'Comp-L-Acer-L' has ID : user2482
                    Wir brauchen den Namen und NICHT die ID!! Also kopieren wir uns Comp-L-Acer-L als Beispiel.
                    Diesen Namen kopieren wir im Script hinter FbDevice.
                  • Jetzt brauchen wir noch den Filter. Auch die wurden ja im ersten Lauf gelistet.
                    Beispiel:
                    Filter named 'Gesperrt' has ID : filtprof4
                    Wir brauchen die ID und NICHT den Namen. Wir kopieren uns also filtprof4 als Beispiel.
                    Diese ID tragen wir dann bei FbProfile ein.
                    Anmerkung ... Ok das könnte man noch auf den Namen umstellen merke ich gerade :-)
                  • FbListOnly jetzt auf false setzen.
                  • Jetzt kommt der Teil wo die Kuh ins Gras beisst :-) Wir lassen das Script laufen.
                    Und wenn nicht alles daneben geht, dann ändert sich wie von Zauberhand der Filter für den entsprechenden Rechner.
                    Und in meinem Fall gingen 2 Jahre Lösungssuche für dieses Problem zu Ende ....

                  Hinweise
                  Mir ist bewusst das man an dem Script noch einiges verbessern könnte. Und ich würde es demnächst auch in github einstellen inkl. Anleitung.
                  Man könnte es auch in einen Adapter überführen. Aber erstmal wäre gut zu wissen ob es bei anderen auch klappt ...
                  Wenn man das Script mit der VIS verheiraten will, dann muss man da noch etwas dran umbauen. Da braucht es dann 2-3 Datenpunkte.
                  Aber ein riesen Drama sollte das nicht sein ...

                  Ok jetzt bin ich gespannt auf das Feedback :-)

                  Bis dahin ...

                  H Offline
                  H Offline
                  hammy1982
                  schrieb am zuletzt editiert von
                  #139

                  @moelski Hallo,

                  ich bin heute auf Ihr Skript gestoßen und würde dieses gerne in ioBroker einsetzen. Nach dem ich aus dem Post Ihr Skript in eingefügt habe und gestartet habe, erhalte ich leider folgende Meldung:
                  23:20:35.489 error javascript.0 (4980) script.js.FritzJava compile failed: at script.js.FritzJava:23

                  Können Sie mir hier weiterhelfen?

                  Mit freundlichen Grüßen

                  Elmar

                  D 1 Antwort Letzte Antwort
                  0
                  • H hammy1982

                    @moelski Hallo,

                    ich bin heute auf Ihr Skript gestoßen und würde dieses gerne in ioBroker einsetzen. Nach dem ich aus dem Post Ihr Skript in eingefügt habe und gestartet habe, erhalte ich leider folgende Meldung:
                    23:20:35.489 error javascript.0 (4980) script.js.FritzJava compile failed: at script.js.FritzJava:23

                    Können Sie mir hier weiterhelfen?

                    Mit freundlichen Grüßen

                    Elmar

                    D Offline
                    D Offline
                    drloksoft
                    schrieb am zuletzt editiert von
                    #140

                    Hi Leute,

                    erstmal vielen Dank für das Mega-Script. Da die Kinder nun mit mehreren Geräten unterwegs sind (Switch und Android), möchte ich gerne alle Geräte gleichzeitig sperren, bzw. freigeben. Könnte ich mit dem Script auch "einfach" die Einstellung zum Zeitraum von "immer" auf "nie" setzen und die Geräte einfach immer in dem Profil lassen? So spare ich mir mehrere Knöpfe.

                    1 Antwort Letzte Antwort
                    0
                    • D Offline
                      D Offline
                      drloksoft
                      schrieb am zuletzt editiert von drloksoft
                      #141

                      EDIT: GELÖST! Ich lasse es aber dennoch hier stehen. Lösung unten!

                      Okay,
                      ich bin lost und muss noch mal eine Frage zum Verständnis stellen, da ich nicht mehrere Geräte mit multiplen buttons in VIS bei Verwendung nur eines Scriptes steuern kann. Über Eure Hilfe würde ich mich sehr freuen :-)

                      Ich habe "DeviceFilterListJson" automatisch befüllen lassen. Das hat funktioniert!
                      Unter anderem gibt es einen Eintrag:

                      {
                          "Device": "iPhone-3",
                          "Profile ID": "filtprof7324",
                          "Profile Name": "Kidsclub",
                          "Usage": "Gesperrt durch Zugangsprofil",
                          "Time": "Onlinezeit aufgebraucht"
                        },
                      

                      Ich habe einen Datenpunkt vom Typ String angelegt.

                      {
                        "common": {
                          "name": "Fire2",
                          "desc": "Manually created",
                          "role": "state",
                          "type": "string",
                          "read": true,
                          "write": true,
                          "def": ""
                        },
                        "type": "state",
                        "from": "system.adapter.admin.0",
                        "user": "system.user.admin",
                        "ts": 1655649177519,
                        "_id": "0_userdata.0.Fire2",
                        "acl": {
                          "object": 1636,
                          "state": 1636,
                          "owner": "system.user.admin",
                          "ownerGroup": "system.group.administrator"
                        }
                      }
                      

                      Nun ändere ich entweder über VIS oder manuell den Datenpunkt zu

                      iPhone-3;filtprof1
                      

                      Oder eben zu

                      iPhone-3;filtprof7324
                      

                      (was die ID zum Profil "Kidsclub" ist)

                      Im Log ist allerdings nichts zu sehen und in der Fritzbox tut sich auch nichts.

                      Meine Settings:

                      // Die IP Der Fritzbox
                      const FbIp          = "192.168.0.1";              
                      // Der User der Fritzbox 
                      // HINWEIS : Den Benutzer leer lassen wenn die Anmeldung an der FB nur mit Passwort erfolgt !
                      const FbUser        = "filter"; 
                      // Das Password der Fritzbox                  
                      const FbPassword    = "filter";   
                      // welcher Rechner soll "bearbeitet" werden                
                      var   FbDevice      = "";   
                      // Das neue Profil für den Rechner              
                      var   FbProfile     = "";  
                      // erweitertes Logging aktivieren für Fehlersuche
                      const FbDebugging   = true;
                      // Keine Änderung an der Fritzbox (true) -> Listet dann nur alle Profile und Rechner               
                      const FbListOnly    = false; 
                      // Device / Filter Liste erzeugen Ja (true), Nein (false)
                      const FbCreateList  = false; 
                      // Datenpunkt (string) für einen automatischen Script Start (muss angelegt werden!)
                      // Der Datenpunkt wir mit Device;Profil beschrieben. Bsp: Comp-L-Pi;filtprof1
                      const FbIobObject   = "0_userdata.0.ChangeDeviceFilter"  
                      // Datenpunkt in den die Device / Filter Liste als JSON geschrieben wird                    
                      const FbIobJsonList = "0_userdata.0.DeviceFilterListJson" 
                       
                      var secChallenge;
                      var secMd5;
                      var secLogin;
                      var secSid;
                      var secProfileNames = [];
                      var secProfileIds   = [];
                      var secDeviceNames  = [];
                      var secDeviceIds    = [];
                      var JsonList        = "";
                       
                      /*******************************************************
                      * Object Trigger Version
                      * Wenn auf einen Datenpunkt getriggert werden soll, dann muss der folgende Block auskommentiert werden. 
                      * FbIobObject muss mit einem string Datenpunkt versehen werden.
                      * Den Static Teil dann auskommentieren !
                      * Diese Variante erlaubt es das Script dynamisch für alle Devices / Profile der FB zu verwenden. 
                      *******************************************************/
                      on({id: FbIobObject, change: "ne"}, function (obj) {
                          console.log("Profile Changer started ... (Version : " + Version + ")");
                          var data = obj.state.val.split(";");
                          if (data.length != 2) {
                              console.log("Wrong parameter : " + obj.state.val);
                              return;
                          }
                       
                          if (FbDebugging){
                              console.log(" > Datapoint : " + data);
                          }
                       
                          console.log("Computer : " + data[0]);
                          console.log("Filter   : " + data[1]);
                          FbDevice  = data[0];
                          FbProfile = data[1];
                       
                          getFbChallenge();
                          
                          console.log("Profile Changer done");
                      });
                       
                      /*******************************************************
                      * Static Version
                      * Die folgenden 3 Zeilen lassen das Script  sofort laufen. 
                      * Dabei sollte der Object Trigger Block auskommentiert werden. 
                      *******************************************************/
                      //console.log("Profile Changer started ... (Version : " + Version + ")");
                      //getFbChallenge();
                      //console.log("Profile Changer done");
                       
                      // Get the Challenge String from the FritzBox
                      // Compute the md5 Hash
                      function getFbChallenge(){
                          console.log("function getFbChallenge");
                          request.get({
                              url:        'http://' + FbIp + '/login_sid.lua?username=' + FbUser,
                              headers:    headers
                          }, function(error, response, body) {
                              if (error) log(error, 'error');
                              //console.log(response);
                              // 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
                              secChallenge = body.match(/Challenge>(.*)<\/Challenge/)[1];
                              console.log(" > Challenge : " + secChallenge);
                       
                              var uft16le = str2rstr_utf16le(secChallenge + "-" +FbPassword );
                              var md5     = rstr_md5(uft16le);
                              secMd5      = rstr2hex(md5);
                                      
                              console.log(" > MD5       : " + 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)
                              secLogin = "response=" + secChallenge + "-" + secMd5 + "&username=" + FbUser;
                       
                              console.log(" > Login     : " + secLogin);
                       
                              getFbSid();
                          });
                      }
                      .... und so weiter ....
                      

                      Die beiden Datenpunkte vom Typ String existieren natürlich im IOB:
                      const FbIobObject = "0_userdata.0.ChangeDeviceFilter"
                      const FbIobJsonList = "0_userdata.0.DeviceFilterListJson"

                      Jede Hilfe ist mir SEHR willkommen ...
                      DANKE!

                      Ich bin so bescheuert. Natürlich muss ich die Änderungen in den Datenpunkt "ChangeDeviceFilter" packen und nicht in einen X-Beliebigen ...

                      1 Antwort Letzte Antwort
                      0
                      • D Offline
                        D Offline
                        dougstar
                        schrieb am zuletzt editiert von
                        #142

                        @moelski Besteht die Möglichkeit, das gesamte Logging zu deaktivieren, oder muss ich die ganzen console.log Zeile auskommentieren?

                        1 Antwort Letzte Antwort
                        0
                        • NegaleinN Offline
                          NegaleinN Offline
                          Negalein
                          Global Moderator
                          schrieb am zuletzt editiert von
                          #143

                          @ilovegym

                          Servus

                          Ich glaube du hast auch dieses Script laufen.
                          Hoffe du kannst mir weiterhelfen.

                          Sperren/Entsperren funktioniert super.
                          Mir wird nur kein JSON angelegt.
                          Was kann das sein?

                          92555dd5-4688-4b3b-8592-fc97bc7bf533-image.png

                          4686fb68-96b4-48ce-a005-274adbd46169-image.png

                          ° Node.js: 20.17.0 NPM: 10.8.2
                          ° Proxmox, Ubuntu 22.04.3 LTS
                          ° Fixer ---> iob fix

                          1 Antwort Letzte Antwort
                          0
                          • RogerWilco 0R Offline
                            RogerWilco 0R Offline
                            RogerWilco 0
                            schrieb am zuletzt editiert von RogerWilco 0
                            #144

                            Hallo zusammende,

                            vielen Dank für das sehr interessante Skript. Allerdings habe ich einen kleinen Bug entdeckt, der mir lange zu schaffen gemacht hat, bis es endlich funktioniert hat.
                            Ich hatte das Problem, dass das Skript durchlief ohne Fehler, jedoch immer das falsche Gerät durch das Zugangsprofil gesperrt wurde und zwar immer das erste nach dem eigentlich zu sperrenden Gerät. Nach Euren Tipps bin ich natürlich erstmal davon ausgegangen, dass dieses Verhalten an unzulässigen Zeichen in den Geräte- oder Profilnamen lag. Doch das habe ich mehrfach überprüft und konnte es dann ausschließen. Der Casus knacksus lag woanders.
                            Es gibt bei der Fritzbox neben den Zugangsprofilen noch eine weitere Möglichkeit, Geräte vom Internet-Zugang zu sperren: nämlich direkt über die Gerätesperre. In der Weboberfläche der Fritzbox (Internet | Filter | Kindersicherung) habe ich dann festgestellt, dass das Zugangsprofil derjenigen Geräte nicht mehr geändert werden kann, bei denen diese Gerätesperre aktiviert war. Und das hat mich dann auf die richtige Fährte gebracht.
                            e57133f1-b500-4fdc-b3f3-4929db52cb55-grafik.png
                            Das obengenannte Skript "verzählt" sich beim Ändern des Zugangsprofils nun um genauso viele Geräte, wie Gerätesperren in der Liste VOR dem entsprechenden Gerät aktiviert sind. In meinem Fall war es ein Gerät (AltesDenkBrett). Gerätesperren in der Liste NACH dem Gerät spielen dabei offenbar keine Rolle.
                            Nachdem ich alle Gerätesperren entfernt hatte, die in der Liste VOR meinem zu sperrenden Gerät aufgeführt waren, hat das Skript einwandfrei und reproduzierbar funktioniert und das richtige Gerät gesperrt.

                            Es ist etwas umständlich zu beschreiben gewesen, aber ich hoffe, es war halbswegs verständlich und hilft dem einen oder anderen, der mit ähnlichen Unwegbarkeiten zu kämpfen hat wie ich.

                            Viele Grüße,
                            Ralf

                            Mein Haus, mein Auto, mein Boot...

                            U 1 Antwort Letzte Antwort
                            0
                            • RogerWilco 0R RogerWilco 0

                              Hallo zusammende,

                              vielen Dank für das sehr interessante Skript. Allerdings habe ich einen kleinen Bug entdeckt, der mir lange zu schaffen gemacht hat, bis es endlich funktioniert hat.
                              Ich hatte das Problem, dass das Skript durchlief ohne Fehler, jedoch immer das falsche Gerät durch das Zugangsprofil gesperrt wurde und zwar immer das erste nach dem eigentlich zu sperrenden Gerät. Nach Euren Tipps bin ich natürlich erstmal davon ausgegangen, dass dieses Verhalten an unzulässigen Zeichen in den Geräte- oder Profilnamen lag. Doch das habe ich mehrfach überprüft und konnte es dann ausschließen. Der Casus knacksus lag woanders.
                              Es gibt bei der Fritzbox neben den Zugangsprofilen noch eine weitere Möglichkeit, Geräte vom Internet-Zugang zu sperren: nämlich direkt über die Gerätesperre. In der Weboberfläche der Fritzbox (Internet | Filter | Kindersicherung) habe ich dann festgestellt, dass das Zugangsprofil derjenigen Geräte nicht mehr geändert werden kann, bei denen diese Gerätesperre aktiviert war. Und das hat mich dann auf die richtige Fährte gebracht.
                              e57133f1-b500-4fdc-b3f3-4929db52cb55-grafik.png
                              Das obengenannte Skript "verzählt" sich beim Ändern des Zugangsprofils nun um genauso viele Geräte, wie Gerätesperren in der Liste VOR dem entsprechenden Gerät aktiviert sind. In meinem Fall war es ein Gerät (AltesDenkBrett). Gerätesperren in der Liste NACH dem Gerät spielen dabei offenbar keine Rolle.
                              Nachdem ich alle Gerätesperren entfernt hatte, die in der Liste VOR meinem zu sperrenden Gerät aufgeführt waren, hat das Skript einwandfrei und reproduzierbar funktioniert und das richtige Gerät gesperrt.

                              Es ist etwas umständlich zu beschreiben gewesen, aber ich hoffe, es war halbswegs verständlich und hilft dem einen oder anderen, der mit ähnlichen Unwegbarkeiten zu kämpfen hat wie ich.

                              Viele Grüße,
                              Ralf

                              U Offline
                              U Offline
                              undeat
                              schrieb am zuletzt editiert von
                              #145

                              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.

                              1 Antwort Letzte Antwort
                              0
                              Antworten
                              • In einem neuen Thema antworten
                              Anmelden zum Antworten
                              • Älteste zuerst
                              • Neuste zuerst
                              • Meiste Stimmen


                              Support us

                              ioBroker
                              Community Adapters
                              Donate

                              651

                              Online

                              32.4k

                              Benutzer

                              81.5k

                              Themen

                              1.3m

                              Beiträge
                              Community
                              Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                              ioBroker Community 2014-2025
                              logo
                              • Anmelden

                              • Du hast noch kein Konto? Registrieren

                              • Anmelden oder registrieren, um zu suchen
                              • Erster Beitrag
                                Letzter Beitrag
                              0
                              • Home
                              • Aktuell
                              • Tags
                              • Ungelesen 0
                              • Kategorien
                              • Unreplied
                              • Beliebt
                              • GitHub
                              • Docu
                              • Hilfe