Skip to content
  • Home
  • Recent
  • Tags
  • 0 Unread 0
  • Categories
  • Unreplied
  • Popular
  • 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

  • Default (No Skin)
  • No Skin
Collapse
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. [Gelöst] Helios KWL - Zugriff auf xml

NEWS

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    17
    1
    3.1k

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    13
    1
    1.1k

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    25
    1
    2.4k

[Gelöst] Helios KWL - Zugriff auf xml

Scheduled Pinned Locked Moved JavaScript
70 Posts 13 Posters 11.6k Views 13 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • TimmerxT Offline
    TimmerxT Offline
    Timmerx
    wrote on last edited by Timmerx
    #61

    Hallo Leute,

    das Skript ist wirklich super, damit kann ich meine Siemens S7 extrem entlasten.

    Kleines Manko ist, dass ich es nicht schaffe den Filterwechsel zurück zustellen.
    Ich hätte in meiner VIS gerne einen Button, um die Resttage zurück zusetzten.

    Hier das Skript inkl. Resttageabfrage, Bypass öffnen/Schließen, Interne Feuchte.

    /*
    ioBroker-Helios-KWL
    IMPORTANT: This script requires at least Node.js v12.x!
    https://github.com/KLVN/ioBroker_Helios-KWL
    */
    
    // SETTINGS ////////////////////////////////////////////////////////////////
    
    const helios_ip = "192.168.178.20";    // IP of Helios KWL
    const helios_password = "12345678";     // Password of Helios KWL (default)
    const datapoint_prefix = "HeliosKWL";   // Prefix for datapoints, e.g. HeliosKWL.Temperatur_Zuluft
    const refresh_interval = 10;            // Refresh every x seconds
    
    const datapoint_names = {
      "w00090": "Partybetrieb_SOLL",        // on/off;duration;speed
      "v00101": "Betriebsart_IST",          // Operating mode (manual = 1, automatic = 0)
      "w00101": "Betriebsart_SOLL",         // Custom variable for operating mode (manual = 1, automatic = 0)
      "v00102": "Luefterstufe_IST",         // Fan speed
      "w00102": "Luefterstufe_SOLL",        // Custom variable for fan speed
      "v00104": "Temperatur_Aussenluft",    // Temperature outdoor air sensor
      "v00105": "Temperatur_Zuluft",        // Temperature supply air sensor
      "v00106": "Temperatur_Fortluft",      // Temperature exhaust air sensor
      "v00107": "Temperatur_Abluft",         // Temperature extract air sensor
      "v01033": "Restlaufzeit in Tagen",             // FILTERWECHSEL
      "v01035": "Temperatur_Bypass_Raum-Ablufttemperatur",
      "v01036": "Temperatur_Bypass_Min_Außenlufttemperatur",
      "v00348": "Drehzahl Zuluft (rpm)",
      "v00349": "Abluftzahl Zuluft (rpm)",
      "v01103": "ZuluftVENTI_Gesamt_h",
      "v01104": "AbluftVENTI_Gesamt_h",
      "v02136": "Feuchte",
      "v02119": "Bypass_AUF/ZU"            // 0= ZU    1= AUF
      // "Register": "Name for the datapoint" (I'm using "vxxxxx" for actual registers and "wxxxxx" for custom datapoints)
    }
    
    ////////////////////////////////////////////////////////////////////////////
    
    // Not necessary; already defined in ioBroker
    // var request= require('request');
    
    // Returns a matching header for login and XML-files
    function createHeader(ip, url, body) {
      var header = {
        headers: {
          "Accept": "*/*",
          "Accept-Encoding": "gzip, deflate",
          "Accept-Language": "de,en-US;q=0.7,en;q=0.3",
          "Connection": "keep-alive",
          "Content-Length": "15",
          "Content-Type": "text/plain;charset=UTF-8",
          "DNT": "1",
          "Referer": "http://" + ip + "/",
          "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36",
          "Host": ip
        },
        url: "http://" + ip + "/" + url,
        body: body,
        method: "POST"
      }
      return header
    }
    
    // Create states from parameter names
    for (let param in datapoint_names) {
      // Different defaults for different datapoints
      if (param == "w00090") {
        createState(datapoint_prefix + "." + datapoint_names[param], "0;10;4");
      } else if (param == "w00101") {
        createState(datapoint_prefix + "." + datapoint_names[param], 0);
      } else {
        // No default given
        createState(datapoint_prefix + "." + datapoint_names[param]);
      }
    }
    
    // Login every 5 minutes
    setInterval(function () {
      request(createHeader(helios_ip, "info.htm", "v00402=" + helios_password));
    }, 300000);
    
    // Refresh values
    setInterval(function () {
      // Load and refresh values from different XML-files (default: page 4 and page 8. Can be extended from 1 to 17 to obtain everything)
      const xmlPages = [4, 8, 11, 12];
      xmlPages.forEach(function (page, index) {
        request(createHeader(helios_ip, "data/werte" + page + ".xml", "xml=/data/werte" + page + ".xml"), function (error, response, result) {
          refreshValues(result);
        });
      });
    }, refresh_interval * 1000);
    
    // Read XML response, extract IDs and values, refresh states with new values
    function refreshValues(xml) {
      const regex = /<ID>(?<ID>v\d{5})<\/ID>\s*?<VA>(?<VALUE>.*?)<\/VA>/gm;
      var elements = xml.matchAll(regex);
    
      for (let element of elements) {
        let { ID, VALUE } = element.groups;
        let NAME = datapoint_names[ID];
    
        // Only refresh values that we have names for
        if (NAME != undefined) {
          setState(datapoint_prefix + "." + NAME, VALUE);
        }
      }
    }
    
    // Takes an URL-path and multiple registers with values to set values and change settings
    function setValues(path, values) {
      var args = arguments;
      var arrayValues = [];
      for (var i = 1; i < args.length; i++) {
        arrayValues.push(args[i]);
      }
      request(createHeader(helios_ip, path + ".htm", arrayValues.join("&")));
    }
    
    // Set fan speed
    function setFanSpeed(speed) {
      // Check if wanted fan speed is a reasonable value
      if ([0, 1, 2, 3, 4].indexOf(speed) >= 0) {
        setValues("info", "v00102=" + speed);
      } else {
        setFanSpeed(0);
      }
    }
    // If specified fan speed was changed, then set fan speed accordingly
    on({ id: "javascript.0." + datapoint_prefix + "." + datapoint_names["w00102"], change: "any" }, async function (obj) {
      var value = obj.state.val;
      setFanSpeed(value);
    });
    
    // Set party mode using following scheme:
    // onOff;duration;speed, e.g.
    // "1;10;4" = turn on party mode for 10 minutes and set fan speed to 4
    // "2;10;4" = invalid
    // "0;10;4" = turn off party mode
    function setPartyMode(onOff, duration, speed) {
      // Only allow reasonable values
      if (([0, 1].indexOf(onOff) >= 0) && (duration > 0) && (duration <= 180) && ([0, 1, 2, 3, 4].indexOf(speed) >= 0)) {
        setValues("party", "v00094=" + onOff, "v00091=" + duration, "v00092=" + speed);
      }
    }
    // If specified party mode was changed, then mode accordingly
    on({ id: "javascript.0." + datapoint_prefix + "." + datapoint_names["w00090"], change: "any" }, async function (obj) {
      var value = obj.state.val;
      var values = value.split(";");
      setPartyMode(parseInt(values[0], 10), parseInt(values[1], 10), parseInt(values[2], 10));
    });
    
    // Set operating mode
    function setOperatingMode(onOff) {
      // Only allow reasonable values
      if ([0, 1].indexOf(onOff) >= 0) {
        setValues("info", "v00101=" + onOff);
      }
    }
    // If specified party mode was changed, then mode accordingly
    on({ id: "javascript.0." + datapoint_prefix + "." + datapoint_names["w00101"], change: "any" }, async function (obj) {
      var value = obj.state.val;
      setOperatingMode(value);
    });
    
    
    
    
    createState("setBypass_AUF", function () {
    });
    on({id: 's7.0.Markers.1014.Helios_Sommerbypass', val: true}, function (obj) {
      var value = obj.state.val;
      var oldValue = obj.oldState.val;
      setValues("gear", "v01036=20");
    
    });
    
    createState("setBypass_ZU", function () {
    });
    on({id: 's7.0.Markers.1014.Helios_Sommerbypass', val: false}, function (obj) {
      var value = obj.state.val;
      var oldValue = obj.oldState.val;
      setValues("gear", "v01036=30");
    
    });
    
    
    
    // ADDITIONAL SCRIPTS (see github.com/KLVN/ioBroker_Helios-KWL) ////////////
    
    // ...insert additional scripts here
    
    KLVNK 1 Reply Last reply
    0
    • TimmerxT Timmerx

      Hallo Leute,

      das Skript ist wirklich super, damit kann ich meine Siemens S7 extrem entlasten.

      Kleines Manko ist, dass ich es nicht schaffe den Filterwechsel zurück zustellen.
      Ich hätte in meiner VIS gerne einen Button, um die Resttage zurück zusetzten.

      Hier das Skript inkl. Resttageabfrage, Bypass öffnen/Schließen, Interne Feuchte.

      /*
      ioBroker-Helios-KWL
      IMPORTANT: This script requires at least Node.js v12.x!
      https://github.com/KLVN/ioBroker_Helios-KWL
      */
      
      // SETTINGS ////////////////////////////////////////////////////////////////
      
      const helios_ip = "192.168.178.20";    // IP of Helios KWL
      const helios_password = "12345678";     // Password of Helios KWL (default)
      const datapoint_prefix = "HeliosKWL";   // Prefix for datapoints, e.g. HeliosKWL.Temperatur_Zuluft
      const refresh_interval = 10;            // Refresh every x seconds
      
      const datapoint_names = {
        "w00090": "Partybetrieb_SOLL",        // on/off;duration;speed
        "v00101": "Betriebsart_IST",          // Operating mode (manual = 1, automatic = 0)
        "w00101": "Betriebsart_SOLL",         // Custom variable for operating mode (manual = 1, automatic = 0)
        "v00102": "Luefterstufe_IST",         // Fan speed
        "w00102": "Luefterstufe_SOLL",        // Custom variable for fan speed
        "v00104": "Temperatur_Aussenluft",    // Temperature outdoor air sensor
        "v00105": "Temperatur_Zuluft",        // Temperature supply air sensor
        "v00106": "Temperatur_Fortluft",      // Temperature exhaust air sensor
        "v00107": "Temperatur_Abluft",         // Temperature extract air sensor
        "v01033": "Restlaufzeit in Tagen",             // FILTERWECHSEL
        "v01035": "Temperatur_Bypass_Raum-Ablufttemperatur",
        "v01036": "Temperatur_Bypass_Min_Außenlufttemperatur",
        "v00348": "Drehzahl Zuluft (rpm)",
        "v00349": "Abluftzahl Zuluft (rpm)",
        "v01103": "ZuluftVENTI_Gesamt_h",
        "v01104": "AbluftVENTI_Gesamt_h",
        "v02136": "Feuchte",
        "v02119": "Bypass_AUF/ZU"            // 0= ZU    1= AUF
        // "Register": "Name for the datapoint" (I'm using "vxxxxx" for actual registers and "wxxxxx" for custom datapoints)
      }
      
      ////////////////////////////////////////////////////////////////////////////
      
      // Not necessary; already defined in ioBroker
      // var request= require('request');
      
      // Returns a matching header for login and XML-files
      function createHeader(ip, url, body) {
        var header = {
          headers: {
            "Accept": "*/*",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "de,en-US;q=0.7,en;q=0.3",
            "Connection": "keep-alive",
            "Content-Length": "15",
            "Content-Type": "text/plain;charset=UTF-8",
            "DNT": "1",
            "Referer": "http://" + ip + "/",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36",
            "Host": ip
          },
          url: "http://" + ip + "/" + url,
          body: body,
          method: "POST"
        }
        return header
      }
      
      // Create states from parameter names
      for (let param in datapoint_names) {
        // Different defaults for different datapoints
        if (param == "w00090") {
          createState(datapoint_prefix + "." + datapoint_names[param], "0;10;4");
        } else if (param == "w00101") {
          createState(datapoint_prefix + "." + datapoint_names[param], 0);
        } else {
          // No default given
          createState(datapoint_prefix + "." + datapoint_names[param]);
        }
      }
      
      // Login every 5 minutes
      setInterval(function () {
        request(createHeader(helios_ip, "info.htm", "v00402=" + helios_password));
      }, 300000);
      
      // Refresh values
      setInterval(function () {
        // Load and refresh values from different XML-files (default: page 4 and page 8. Can be extended from 1 to 17 to obtain everything)
        const xmlPages = [4, 8, 11, 12];
        xmlPages.forEach(function (page, index) {
          request(createHeader(helios_ip, "data/werte" + page + ".xml", "xml=/data/werte" + page + ".xml"), function (error, response, result) {
            refreshValues(result);
          });
        });
      }, refresh_interval * 1000);
      
      // Read XML response, extract IDs and values, refresh states with new values
      function refreshValues(xml) {
        const regex = /<ID>(?<ID>v\d{5})<\/ID>\s*?<VA>(?<VALUE>.*?)<\/VA>/gm;
        var elements = xml.matchAll(regex);
      
        for (let element of elements) {
          let { ID, VALUE } = element.groups;
          let NAME = datapoint_names[ID];
      
          // Only refresh values that we have names for
          if (NAME != undefined) {
            setState(datapoint_prefix + "." + NAME, VALUE);
          }
        }
      }
      
      // Takes an URL-path and multiple registers with values to set values and change settings
      function setValues(path, values) {
        var args = arguments;
        var arrayValues = [];
        for (var i = 1; i < args.length; i++) {
          arrayValues.push(args[i]);
        }
        request(createHeader(helios_ip, path + ".htm", arrayValues.join("&")));
      }
      
      // Set fan speed
      function setFanSpeed(speed) {
        // Check if wanted fan speed is a reasonable value
        if ([0, 1, 2, 3, 4].indexOf(speed) >= 0) {
          setValues("info", "v00102=" + speed);
        } else {
          setFanSpeed(0);
        }
      }
      // If specified fan speed was changed, then set fan speed accordingly
      on({ id: "javascript.0." + datapoint_prefix + "." + datapoint_names["w00102"], change: "any" }, async function (obj) {
        var value = obj.state.val;
        setFanSpeed(value);
      });
      
      // Set party mode using following scheme:
      // onOff;duration;speed, e.g.
      // "1;10;4" = turn on party mode for 10 minutes and set fan speed to 4
      // "2;10;4" = invalid
      // "0;10;4" = turn off party mode
      function setPartyMode(onOff, duration, speed) {
        // Only allow reasonable values
        if (([0, 1].indexOf(onOff) >= 0) && (duration > 0) && (duration <= 180) && ([0, 1, 2, 3, 4].indexOf(speed) >= 0)) {
          setValues("party", "v00094=" + onOff, "v00091=" + duration, "v00092=" + speed);
        }
      }
      // If specified party mode was changed, then mode accordingly
      on({ id: "javascript.0." + datapoint_prefix + "." + datapoint_names["w00090"], change: "any" }, async function (obj) {
        var value = obj.state.val;
        var values = value.split(";");
        setPartyMode(parseInt(values[0], 10), parseInt(values[1], 10), parseInt(values[2], 10));
      });
      
      // Set operating mode
      function setOperatingMode(onOff) {
        // Only allow reasonable values
        if ([0, 1].indexOf(onOff) >= 0) {
          setValues("info", "v00101=" + onOff);
        }
      }
      // If specified party mode was changed, then mode accordingly
      on({ id: "javascript.0." + datapoint_prefix + "." + datapoint_names["w00101"], change: "any" }, async function (obj) {
        var value = obj.state.val;
        setOperatingMode(value);
      });
      
      
      
      
      createState("setBypass_AUF", function () {
      });
      on({id: 's7.0.Markers.1014.Helios_Sommerbypass', val: true}, function (obj) {
        var value = obj.state.val;
        var oldValue = obj.oldState.val;
        setValues("gear", "v01036=20");
      
      });
      
      createState("setBypass_ZU", function () {
      });
      on({id: 's7.0.Markers.1014.Helios_Sommerbypass', val: false}, function (obj) {
        var value = obj.state.val;
        var oldValue = obj.oldState.val;
        setValues("gear", "v01036=30");
      
      });
      
      
      
      // ADDITIONAL SCRIPTS (see github.com/KLVN/ioBroker_Helios-KWL) ////////////
      
      // ...insert additional scripts here
      
      KLVNK Offline
      KLVNK Offline
      KLVN
      wrote on last edited by
      #62

      @timmerx sagte in [Gelöst] Helios KWL - Zugriff auf xml:

      Hallo Leute,

      das Skript ist wirklich super, damit kann ich meine Siemens S7 extrem entlasten.

      Freut mich, dass es funktioniert und du es auch gleich noch erweitert hast :)

      Kleines Manko ist, dass ich es nicht schaffe den Filterwechsel zurück zustellen.
      Ich hätte in meiner VIS gerne einen Button, um die Resttage zurück zusetzten.

      Funktioniert das Code-Stück von GitHub nicht? Da brauchst du nicht mal einen Button, sondern es wird automatisch immer zurückgesetzt. Ich habe jetzt seit fast einem Jahr meine Helios nicht mehr angefasst (den Filter sollte ich aber wohl wirklich mal wechseln :sweat_smile: )

      // Reset change interval of filter every month
      schedule("0 5 1 * *", function () {
        setValues("gear", "v01034=1");
      });
      

      Das Register zum Zurücksetzen findest du im Quellcode vom "Restlaufzeit neu starten"-Button. Vielleicht ist das bei dir anders (?)
      63baecdf-ad80-4b3a-917d-4af0c168071b-image.png

      VIS benutze ich nicht allzu sehr, deshalb fällt mir da jetzt nur diese dreckige Lösung ein:

      • neuer Datenpunkt (Bool, false), z.B. resetHelios
      • In VIS dann einen Button, der diesen Datenpunkt auf true setzen kann
      • In deinem Skript dann auf eine Veränderungen von resetHelios warten, dann den Code zum resetten ausführen und danach den Datenpunkt wieder auf false setzen
      T 1 Reply Last reply
      0
      • KLVNK KLVN

        @timmerx sagte in [Gelöst] Helios KWL - Zugriff auf xml:

        Hallo Leute,

        das Skript ist wirklich super, damit kann ich meine Siemens S7 extrem entlasten.

        Freut mich, dass es funktioniert und du es auch gleich noch erweitert hast :)

        Kleines Manko ist, dass ich es nicht schaffe den Filterwechsel zurück zustellen.
        Ich hätte in meiner VIS gerne einen Button, um die Resttage zurück zusetzten.

        Funktioniert das Code-Stück von GitHub nicht? Da brauchst du nicht mal einen Button, sondern es wird automatisch immer zurückgesetzt. Ich habe jetzt seit fast einem Jahr meine Helios nicht mehr angefasst (den Filter sollte ich aber wohl wirklich mal wechseln :sweat_smile: )

        // Reset change interval of filter every month
        schedule("0 5 1 * *", function () {
          setValues("gear", "v01034=1");
        });
        

        Das Register zum Zurücksetzen findest du im Quellcode vom "Restlaufzeit neu starten"-Button. Vielleicht ist das bei dir anders (?)
        63baecdf-ad80-4b3a-917d-4af0c168071b-image.png

        VIS benutze ich nicht allzu sehr, deshalb fällt mir da jetzt nur diese dreckige Lösung ein:

        • neuer Datenpunkt (Bool, false), z.B. resetHelios
        • In VIS dann einen Button, der diesen Datenpunkt auf true setzen kann
        • In deinem Skript dann auf eine Veränderungen von resetHelios warten, dann den Code zum resetten ausführen und danach den Datenpunkt wieder auf false setzen
        T Offline
        T Offline
        tombox
        wrote on last edited by
        #63

        @klvn Würde es nicht sinn machen ein Adapter aus dem Script zu machen?

        1 Reply Last reply
        0
        • TimmerxT Offline
          TimmerxT Offline
          Timmerx
          wrote on last edited by Timmerx
          #64

          Hi,

          das Github Codestück // Reset change interval of filter every month schedule("0 5 1 * *", function () { setValues("gear", "v01034=1"); });

          habe ich so nicht getestet, sonderen
          schedule("0 5 1 * *", ..... direkt versucht mit einem Butten zu ersetzen.

          Eine monatliche zurücksetzen halte ich nicht für sinnvoll, da ich die Filter wechseln will (schon weil die Anlage mit der Zeit immer lauter wird mit alten / vollen Filtern)

          Und weil ich auch nicht mehr auf die Helios Weboberfläche will, wäre ein solcher Button wirklich toll

          Ich werde mich heute vormittag nochmal hinsetzen und bissel rum probieren.

          Grüße

          1 Reply Last reply
          0
          • TimmerxT Offline
            TimmerxT Offline
            Timmerx
            wrote on last edited by
            #65

            So ich habe in der Vis einen Button ( 1 / 0 ) erstellt, diesen habe ich mit der Variablen javascript.0.RESET_RESTTAGE_HELIOS verknüpft und das Skript wie folgt angepasst.

            // Resttage reset
            createState("RESET_RESTTAGE_HELIOS", function () {
            });
            on({id: 'javascript.0.RESET_RESTTAGE_HELIOS', change: "ne"}, function (obj) {
              var value = obj.state.val;
              var oldValue = obj.oldState.val;
              setValues("gear", "v01034=1");
              console.log('Reset ausgeführt');
            
            });
            var Resttage_Skript;
            // Resttage Filterwechsel
            on({id: 'javascript.0.RESET_RESTTAGE_HELIOS', change: "ne"}, function (obj) {
              var value = obj.state.val;
              var oldValue = obj.oldState.val;
              Resttage_Skript = setTimeout(function () {
                setState("javascript.0.RESET_RESTTAGE_HELIOS", 0);
              }, 15000);
            });
            (function () {if (Resttage_Skript) {clearTimeout(Resttage_Skript); Resttage_Skript = null;}})();
            
            //Resttage umrechnen
            createState("Restfiltertage_berechnet", function () {
            });
            on({id: 'javascript.0.HeliosKWL.Restlaufzeit in Tagen', change: "ne"}, function (obj) {
              var value = obj.state.val;
              var oldValue = obj.oldState.val;
              setState("javascript.0.Restfiltertage_berechnet", (Math.round(getState("javascript.0.HeliosKWL.Restlaufzeit in Tagen").val / 1443.1)));
              console.log((['Lüftungsanlage: Filterwechsel in ',getState("javascript.0.Restfiltertage_berechnet").val,' Tagen!'].join('')));
            });
            

            Im Skript wird jetzt der Button nach 15 Sekunden wieder auf 0 zurückgesetzt.

            Zusätzlich werden die Resttage in eine lesbare Zahl (ohne Komma) umgerechnet.

            Das zurücksetzten der Resttage hat leider nur einmal funktioniert.....

            KLVNK 1 Reply Last reply
            0
            • TimmerxT Timmerx

              So ich habe in der Vis einen Button ( 1 / 0 ) erstellt, diesen habe ich mit der Variablen javascript.0.RESET_RESTTAGE_HELIOS verknüpft und das Skript wie folgt angepasst.

              // Resttage reset
              createState("RESET_RESTTAGE_HELIOS", function () {
              });
              on({id: 'javascript.0.RESET_RESTTAGE_HELIOS', change: "ne"}, function (obj) {
                var value = obj.state.val;
                var oldValue = obj.oldState.val;
                setValues("gear", "v01034=1");
                console.log('Reset ausgeführt');
              
              });
              var Resttage_Skript;
              // Resttage Filterwechsel
              on({id: 'javascript.0.RESET_RESTTAGE_HELIOS', change: "ne"}, function (obj) {
                var value = obj.state.val;
                var oldValue = obj.oldState.val;
                Resttage_Skript = setTimeout(function () {
                  setState("javascript.0.RESET_RESTTAGE_HELIOS", 0);
                }, 15000);
              });
              (function () {if (Resttage_Skript) {clearTimeout(Resttage_Skript); Resttage_Skript = null;}})();
              
              //Resttage umrechnen
              createState("Restfiltertage_berechnet", function () {
              });
              on({id: 'javascript.0.HeliosKWL.Restlaufzeit in Tagen', change: "ne"}, function (obj) {
                var value = obj.state.val;
                var oldValue = obj.oldState.val;
                setState("javascript.0.Restfiltertage_berechnet", (Math.round(getState("javascript.0.HeliosKWL.Restlaufzeit in Tagen").val / 1443.1)));
                console.log((['Lüftungsanlage: Filterwechsel in ',getState("javascript.0.Restfiltertage_berechnet").val,' Tagen!'].join('')));
              });
              

              Im Skript wird jetzt der Button nach 15 Sekunden wieder auf 0 zurückgesetzt.

              Zusätzlich werden die Resttage in eine lesbare Zahl (ohne Komma) umgerechnet.

              Das zurücksetzten der Resttage hat leider nur einmal funktioniert.....

              KLVNK Offline
              KLVNK Offline
              KLVN
              wrote on last edited by
              #66

              @tombox sagte in [Gelöst] Helios KWL - Zugriff auf xml:

              @klvn Würde es nicht sinn machen ein Adapter aus dem Script zu machen?

              Könnte man machen, aber ich habe mich bewusst dagegen entschieden, weil ich kein Fan von aufgeblasenen Adaptern bin, wenn sich alles mit nur ca. 140 Codezeilen im Skript-Adapter erledigen lässt. Hinzu kommt noch, dass es sowieso nur wenige Helios-Benutzer gibt und diese können wiederum auch nur mit diesem Skript arbeiten und sind zufrieden (wie der Thread zeigt). Und auch gerade diese eigenen Anpassungen, wie jetzt z.B. der Button von Timmerx oder meine Zusatzfunktionen (Zeitpläne, die nur laufen, wenn auch jemand Zuhause ist oder dass mein Bad abgesaugt wird, wenn die Dusche läuft) sind in Adaptern einfach nicht möglich (ohne viel Aufwand), sodass man sowieso auf den Skript-Adapter setzen muss.

              Ein Adapter sieht schicker aus, aber ich habe das Skript schon so einfach wie möglich gehalten, sodass man eigentlich nur Copy & Paste, die IP-Adresse eintragen und das Skript starten muss.


              @timmerx sagte in [Gelöst] Helios KWL - Zugriff auf xml:

              Das zurücksetzten der Resttage hat leider nur einmal funktioniert.....

              Probiere es in 24h nochmal, dann ist auch wieder ein Tag vergangen, den du zurücksetzen kannst.
              Statt dem setTimeout würde ich ein setStateDelayed nehmen, so spart man sich etwas Code.

              // Resttage reset
              createState("RESET_RESTTAGE_HELIOS", function () {
              });
              on({id: 'javascript.0.RESET_RESTTAGE_HELIOS', change: "ne"}, function (obj) {
                var value = obj.state.val;
                var oldValue = obj.oldState.val;
              
                // Falls auf 0 gesetzt wurde, breche ab. Wenn 1, dann mache Reset
                if(!value) return;
              
                setValues("gear", "v01034=1");
                console.log('Reset ausgeführt');
              
                // Setze in 15 Sekunden zurück auf 0
                setStateDelayed("javascript.0.RESET_RESTTAGE_HELIOS", 0, 15000);
              });
              

              Ist ungetestet, weil ich das jetzt nur im Browser geschrieben habe. Bei dem if bin ich mir nicht sicher, ob man das überhaupt braucht, die Idee dahinter war aber:

              • Das on reagiert auf jede Veränderung
              • Du drückst den Button, der Wert wird zu 1 -> Änderung
              • Das on wird jetzt ausgeführt
              • 15 Sekunden später wird wieder auf 0 gesetzt -> Änderung
              • ...der Kreislauf geht los, weil es sich immer wieder selbst triggert (?)

              Mit dem if testet man jetzt, ob der Wert 0 ist, denn dann wurde ja gerade zurückgesetzt und wir wollen es nicht nochmal machen.

              Man könnte auch ein on({id: 'javascript.0.RESET_RESTTAGE_HELIOS', change: "gt"}, function (obj) {}) nehmen (change: "gt"), dann wird nur ausgelöst, wenn man von 0 auf 1 gegangen ist, also den Button gedrückt hat.

              T 2 Replies Last reply
              0
              • KLVNK KLVN

                @tombox sagte in [Gelöst] Helios KWL - Zugriff auf xml:

                @klvn Würde es nicht sinn machen ein Adapter aus dem Script zu machen?

                Könnte man machen, aber ich habe mich bewusst dagegen entschieden, weil ich kein Fan von aufgeblasenen Adaptern bin, wenn sich alles mit nur ca. 140 Codezeilen im Skript-Adapter erledigen lässt. Hinzu kommt noch, dass es sowieso nur wenige Helios-Benutzer gibt und diese können wiederum auch nur mit diesem Skript arbeiten und sind zufrieden (wie der Thread zeigt). Und auch gerade diese eigenen Anpassungen, wie jetzt z.B. der Button von Timmerx oder meine Zusatzfunktionen (Zeitpläne, die nur laufen, wenn auch jemand Zuhause ist oder dass mein Bad abgesaugt wird, wenn die Dusche läuft) sind in Adaptern einfach nicht möglich (ohne viel Aufwand), sodass man sowieso auf den Skript-Adapter setzen muss.

                Ein Adapter sieht schicker aus, aber ich habe das Skript schon so einfach wie möglich gehalten, sodass man eigentlich nur Copy & Paste, die IP-Adresse eintragen und das Skript starten muss.


                @timmerx sagte in [Gelöst] Helios KWL - Zugriff auf xml:

                Das zurücksetzten der Resttage hat leider nur einmal funktioniert.....

                Probiere es in 24h nochmal, dann ist auch wieder ein Tag vergangen, den du zurücksetzen kannst.
                Statt dem setTimeout würde ich ein setStateDelayed nehmen, so spart man sich etwas Code.

                // Resttage reset
                createState("RESET_RESTTAGE_HELIOS", function () {
                });
                on({id: 'javascript.0.RESET_RESTTAGE_HELIOS', change: "ne"}, function (obj) {
                  var value = obj.state.val;
                  var oldValue = obj.oldState.val;
                
                  // Falls auf 0 gesetzt wurde, breche ab. Wenn 1, dann mache Reset
                  if(!value) return;
                
                  setValues("gear", "v01034=1");
                  console.log('Reset ausgeführt');
                
                  // Setze in 15 Sekunden zurück auf 0
                  setStateDelayed("javascript.0.RESET_RESTTAGE_HELIOS", 0, 15000);
                });
                

                Ist ungetestet, weil ich das jetzt nur im Browser geschrieben habe. Bei dem if bin ich mir nicht sicher, ob man das überhaupt braucht, die Idee dahinter war aber:

                • Das on reagiert auf jede Veränderung
                • Du drückst den Button, der Wert wird zu 1 -> Änderung
                • Das on wird jetzt ausgeführt
                • 15 Sekunden später wird wieder auf 0 gesetzt -> Änderung
                • ...der Kreislauf geht los, weil es sich immer wieder selbst triggert (?)

                Mit dem if testet man jetzt, ob der Wert 0 ist, denn dann wurde ja gerade zurückgesetzt und wir wollen es nicht nochmal machen.

                Man könnte auch ein on({id: 'javascript.0.RESET_RESTTAGE_HELIOS', change: "gt"}, function (obj) {}) nehmen (change: "gt"), dann wird nur ausgelöst, wenn man von 0 auf 1 gegangen ist, also den Button gedrückt hat.

                T Offline
                T Offline
                tombox
                wrote on last edited by
                #67

                @klvn Ich denke mal ein Adapter hat keine 140 zeilen. Es ist auch leichter nutzbar als das aktuelle Skript in einem thread zu finden. Ich kann ja mal schnell einen erstellen und du kannst entscheiden wo du weiter dran arbeiten willst.

                1 Reply Last reply
                0
                • KLVNK KLVN

                  @tombox sagte in [Gelöst] Helios KWL - Zugriff auf xml:

                  @klvn Würde es nicht sinn machen ein Adapter aus dem Script zu machen?

                  Könnte man machen, aber ich habe mich bewusst dagegen entschieden, weil ich kein Fan von aufgeblasenen Adaptern bin, wenn sich alles mit nur ca. 140 Codezeilen im Skript-Adapter erledigen lässt. Hinzu kommt noch, dass es sowieso nur wenige Helios-Benutzer gibt und diese können wiederum auch nur mit diesem Skript arbeiten und sind zufrieden (wie der Thread zeigt). Und auch gerade diese eigenen Anpassungen, wie jetzt z.B. der Button von Timmerx oder meine Zusatzfunktionen (Zeitpläne, die nur laufen, wenn auch jemand Zuhause ist oder dass mein Bad abgesaugt wird, wenn die Dusche läuft) sind in Adaptern einfach nicht möglich (ohne viel Aufwand), sodass man sowieso auf den Skript-Adapter setzen muss.

                  Ein Adapter sieht schicker aus, aber ich habe das Skript schon so einfach wie möglich gehalten, sodass man eigentlich nur Copy & Paste, die IP-Adresse eintragen und das Skript starten muss.


                  @timmerx sagte in [Gelöst] Helios KWL - Zugriff auf xml:

                  Das zurücksetzten der Resttage hat leider nur einmal funktioniert.....

                  Probiere es in 24h nochmal, dann ist auch wieder ein Tag vergangen, den du zurücksetzen kannst.
                  Statt dem setTimeout würde ich ein setStateDelayed nehmen, so spart man sich etwas Code.

                  // Resttage reset
                  createState("RESET_RESTTAGE_HELIOS", function () {
                  });
                  on({id: 'javascript.0.RESET_RESTTAGE_HELIOS', change: "ne"}, function (obj) {
                    var value = obj.state.val;
                    var oldValue = obj.oldState.val;
                  
                    // Falls auf 0 gesetzt wurde, breche ab. Wenn 1, dann mache Reset
                    if(!value) return;
                  
                    setValues("gear", "v01034=1");
                    console.log('Reset ausgeführt');
                  
                    // Setze in 15 Sekunden zurück auf 0
                    setStateDelayed("javascript.0.RESET_RESTTAGE_HELIOS", 0, 15000);
                  });
                  

                  Ist ungetestet, weil ich das jetzt nur im Browser geschrieben habe. Bei dem if bin ich mir nicht sicher, ob man das überhaupt braucht, die Idee dahinter war aber:

                  • Das on reagiert auf jede Veränderung
                  • Du drückst den Button, der Wert wird zu 1 -> Änderung
                  • Das on wird jetzt ausgeführt
                  • 15 Sekunden später wird wieder auf 0 gesetzt -> Änderung
                  • ...der Kreislauf geht los, weil es sich immer wieder selbst triggert (?)

                  Mit dem if testet man jetzt, ob der Wert 0 ist, denn dann wurde ja gerade zurückgesetzt und wir wollen es nicht nochmal machen.

                  Man könnte auch ein on({id: 'javascript.0.RESET_RESTTAGE_HELIOS', change: "gt"}, function (obj) {}) nehmen (change: "gt"), dann wird nur ausgelöst, wenn man von 0 auf 1 gegangen ist, also den Button gedrückt hat.

                  T Offline
                  T Offline
                  tombox
                  wrote on last edited by tombox
                  #68

                  @klvn Ich habe mal ein Adapter erstellt sind zwar 200 Zeilen geworden aber dafür kann er alle States einlesen und bearbeiten, also viel weniger Skriptaufwand notwendig.

                  Bitte mal testen. Ich habe es blind programmiert da ich keine Helios habe

                  https://forum.iobroker.net/topic/47762/test-helios-kwl-v0-0-x

                  1 Reply Last reply
                  0
                  • KLVNK Offline
                    KLVNK Offline
                    KLVN
                    wrote on last edited by
                    #69

                    @tombox sagte in [Gelöst] Helios KWL - Zugriff auf xml:

                    Es ist auch leichter nutzbar als das aktuelle Skript in einem thread zu finden.

                    Ja das stimmt, der erste Ort an dem gesucht wird, ist die Adapterliste im ioBroker und nicht das Forum. Ich habe diesen Thread hier auch nur gekapert und keinen eigenen für eine Vorstellung erstellt :S


                    @tombox sagte in [Gelöst] Helios KWL - Zugriff auf xml:

                    Bitte mal testen. Ich habe es blind programmiert da ich keine Helios habe

                    Nicht schlecht, dafür dass du es blind ohne Testgerät gemacht hat :+1: Ich sehe gerade, dass du auch schon viel Erfahrung im Bau von Adaptern hast. Zu Beginn wurden die Werte auch geladen, doch dann stößt dein Adapter auf dasselbe Problem, wie mein Skript: Man darf/kann nicht alle XML-Seiten auf einmal abfragen [1]. Entweder man baut Verzögerungen ein oder nimmt nur ausgewählte Seiten, die man braucht. Ein Input-Feld mit den gewünschten Seiten lässt sich im Adapter-Fenster ja aber auch einfügen.

                    Letztendlich ist der Adapter einfacher zu bedienen und zu finden. Ein paar Dinge, wie benutzerdefinierte XML-Seiten lassen sich auch integrieren, doch mit den hohen RAM-Verbräuchen von Adaptern kann ich mich immer noch nicht anfreunden. Der Helios-Adapter ist mit 44MB auf Platz 3 bei mir, hinter Admin (60MB) und Javascript (99MB mit 12 laufenden Skripten; 80MB wenn nur mein Helios-Skript läuft). Wie gesagt, bin beeindruckt, wie du das zusammengeschustert hast, will das auch nicht schlechtreden und vielleicht springen hier auch ein paar Leute im Thread und über die Adapter-Suche an.

                    [1] Hier sind die Beiträge dazu:
                    @klvn sagte in [Gelöst] Helios KWL - Zugriff auf xml:

                    @moehre sagte in [Gelöst] Helios KWL - Zugriff auf xml:

                    refreshValues wird ausgeführt, bevor eine Rückmeldung vom Webserver kommt.

                    [...] Meine Vermutung ist jetzt, dass die Helios-Anlage nicht zu viele Anfragen in sehr kurzer Zeit beantworten will und deshalb teilweise abbricht. [...]

                    @moehre sagte in [Gelöst] Helios KWL - Zugriff auf xml:

                    Auch eine Verzögerung um x ms hat nichts gebracht.

                    Wo und wie hast du diese Verzögerung eingebaut? Wenn man xmlPages.forEach() langsamer laufen lässt, sollte es eigentlich gehen, habe es jetzt aber auch nicht getestet. Leider gibt es auch keine einzelne XML-Seite, auf der alle Werte auf einmal sind.

                    Hier sonst nochmal das Log:

                    host.ioBroker
                    2021-09-15 13:12:39.826	error	instance system.adapter.helios.0 terminated with code 6 (UNCAUGHT_EXCEPTION)
                    
                    helios.0
                    2021-09-15 13:12:38.658	warn	State value to set for "helios.0.Werksreset" has value "0" less than min "1"
                    
                    helios.0
                    2021-09-15 13:12:38.638	warn	State value to set for "helios.0.Auslieferzustand_WZU" has value "0" less than min "1"
                    
                    helios.0
                    2021-09-15 13:12:38.566	warn	Terminated (UNCAUGHT_EXCEPTION): Without reason
                    
                    helios.0
                    2021-09-15 13:12:38.558	info	terminating
                    
                    helios.0
                    2021-09-15 13:12:38.538	error	The id is empty! Please provide a valid id.
                    
                    helios.0
                    2021-09-15 13:12:38.537	error	Error: The id is empty! Please provide a valid id. at validateId (/opt/iobroker/node_modules/iobroker.js-controller/lib/adapter.js:501:19) at Helios.setState (/opt/iobroker/node_modules/iobroker.js-controller/lib/adapter.js:6081:17) at Helios.parseResult (/opt/iobroker/node_modules/iobroker.helios/main.js:143:18) at runNextTicks (internal/process/task_queues.js:62:5) at processImmediate (internal/timers.js:434:9)
                    
                    helios.0
                    2021-09-15 13:12:38.531	error	unhandled promise rejection: The id is empty! Please provide a valid id.
                    
                    helios.0
                    2021-09-15 13:12:38.530	error	Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().
                    
                    helios.0
                    2021-09-15 13:12:38.527	error	Error: The id is empty! Please provide a valid id.
                    
                    helios.0
                    2021-09-15 13:12:38.404	error	"<html><head><title>404 Fehler</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"> </head><body><div align=\"center\"><p>easyControls: Basic Modul SD-Card Error:4 </p></div></body></html>\r\n\r\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<PARAMETER>\n<LANG>de</LANG>\n<ID>v01306</ID>\n<VA>00001000000000000000000010000001</VA>\n<ID>v00025</I"
                    
                    helios.0
                    2021-09-15 13:12:38.402	error	Error: Request failed with status code 404
                    
                    helios.0
                    2021-09-15 13:12:38.401	error	Page: 15
                    
                    helios.0
                    2021-09-15 13:12:38.230	warn	State value to set for "helios.0.Zeitzone_Abweichung von_GMT" has value "2" less than min "12"
                    
                    helios.0
                    2021-09-15 13:12:37.737	error	Error: connect ECONNRESET 192.168.178.35:80
                    
                    helios.0
                    2021-09-15 13:12:37.736	error	Page: 5
                    
                    helios.0
                    2021-09-15 13:12:37.734	error	Error: connect ECONNRESET 192.168.178.35:80
                    
                    helios.0
                    2021-09-15 13:12:37.733	error	Page: 4
                    
                    helios.0
                    2021-09-15 13:12:37.731	error	Error: connect ECONNRESET 192.168.178.35:80
                    
                    helios.0
                    2021-09-15 13:12:37.730	error	Page: 3
                    
                    helios.0
                    2021-09-15 13:12:37.728	error	Error: connect ECONNRESET 192.168.178.35:80
                    
                    helios.0
                    2021-09-15 13:12:37.727	error	Page: 2
                    
                    helios.0
                    2021-09-15 13:12:37.725	error	Error: connect ECONNRESET 192.168.178.35:80
                    
                    helios.0
                    2021-09-15 13:12:37.724	error	Page: 1
                    
                    helios.0
                    2021-09-15 13:12:37.342	info	starting. Version 0.0.1 in /opt/iobroker/node_modules/iobroker.helios, node: v12.22.5, js-controller: 3.3.12
                    host.ioBroker
                    2021-09-15 13:12:34.885	info	instance system.adapter.helios.0 started with pid 22299
                    
                    1 Reply Last reply
                    0
                    • T Offline
                      T Offline
                      tombox
                      wrote on last edited by tombox
                      #70

                      @klvn Ich habe mal die aufgetretetenen Fehler behoben und eine 5s waiting eingebaut. Oder gibt es eine Empfehlung?
                      Was auch eigenartig ist 1-5 sind fehlgeschlagen und 6-17 ohne Probleme

                      Einfach neu installieren via github und schauen ob noch fehler kommen

                      Was wird auf den einzelnen seiten angezeigt?

                      Bezüglich des Speicher kann man den Adapter im compact mode betreibten dann benötigt er wie ein skript auch 0MB
                      https://www.iobroker.net/#de/documentation/config/cli.md?iobrokercompactenabledisableonoff

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      Support us

                      ioBroker
                      Community Adapters
                      Donate

                      643

                      Online

                      32.6k

                      Users

                      82.3k

                      Topics

                      1.3m

                      Posts
                      Community
                      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                      ioBroker Community 2014-2025
                      logo
                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Home
                      • Recent
                      • Tags
                      • Unread 0
                      • Categories
                      • Unreplied
                      • Popular
                      • GitHub
                      • Docu
                      • Hilfe