Navigation

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

    NEWS

    • Amazon Alexa - ioBroker Skill läuft aus ?

    • Monatsrückblick – September 2025

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

    O
    • Profile
    • Following 0
    • Followers 4
    • Topics 32
    • Posts 1004
    • Best 96
    • Groups 3

    oxident

    @oxident

    106
    Reputation
    130
    Profile views
    1004
    Posts
    4
    Followers
    0
    Following
    Joined Last Online

    oxident Follow
    Pro Starter Most Active

    Best posts made by oxident

    • [Javascript] Midas (Aquatemp) Poolheizung

      Entwicklung des Skripts eingestellt -> bitte den Adapter https://github.com/MiRo1310/ioBroker.midas-aquatemp testen

      Hallo!

      Ich habe eine Poolsana InverPro Wärmepumpe (Hersteller ist Midas) mit WLAN-Modul für meinen Pool und dachte mir, das kann man bestimmt integrieren 😉

      Ihr müsst im oberen Teil des Skripts Eure Zugangsdaten eintragen. Dann noch, ganz wichtig, den apiLevel entweder auf 1 (für Anlagen, die schon vor einigen Monaten registriert wurden) oder 3 (für neuere Anlagen) setzen. Im Zweifelsfall beide Werte probieren.

      Hierbei auch wichtig: Bitte legt Euch einen Zweit-Account an und "teilt" Eure Anlage dann mit diesem. Dies kann man über die App erledigen. Hintergrund ist der, dass der Hersteller immer nur einen gleichzeitigen Login erlaubt.

      Ein- und Ausschalten der Wärmepumpe läuft über den DP "mode". Mit dem DP "silent" kann der Flüstermodus (verringerte Leistung) geschaltet werden und "tempSet" steuert die Zieltemperatur.
      Die restlichen DP sind nur-lesend und hoffentlich selbsterklärend.

      Wenn alles geklappt hat, dann findet ihr unter 0.userdata.0/Poolheizung folgende Datenpunkte:

      81109b84-4832-46ee-ad83-726589b4e626-image.png

      // Midas Poolheizung
      // v0.0.12
      // Changelog:
      // 0.0.12: Ausgangstemperatur des Kompressors (exhaust) sowie Produkt- und Geräte-ID hinzugefügt
      //         neue Produkt-IDs hinzugefügt (ungetestet)
      // 0.0.11: Request zu Acios migriert
      // 0.0.10: Weitere Parameter für andere Gerätetypen hinzugefügt
      // 0.0.8: Testweise Unterstützung von neu registrierten Anlagen
      // 0.0.7: Kleinigkeiten überarbeitet
      //        weitere Modelle hinzugefügt
      // 0.0.6: Gültigkeitsprüfung des Zertifikats deaktiviert (Dank an znyde)
      //        Kompatibilität mit Promo Next Modellen durch generische Product-ID (Dank an znyde)
      // 0.0.5: weitere Abfragewerte hinzugefügt (Kompressor- und Ansaugtemperatur)
      // 0.0.4: Tokenverfall jetzt 60min nach Skriptstart und nicht zu jeder vollen Stunde (Dank an dering)
      // 0.0.3: Datenpunkte beim Start automatisch anlegen (Dank an Andy200877)
      // 0.0.2: Token bei jedem Set-Vorgang prüfen und ggf. neu anfordern (Dank an dering)
      
      // ANFANG konfigurierbare Elemente -----
      const username = "EMAIL";
      var password = "KENNWORT";
      
      const interval = 30; // Abfrageintervall in Sekunden
      
      const dpRoot = "0_userdata.0.Poolheizung"; // Stammordner der Datenpunkte
      
      const apilevel = 3;   // 1: AquaTemp-Accounts, die vor v.1.5.8 erstellt wurden
                            // 2: HiTemp-Accounts
                            // 3: AquaTemp-Accounts, die mit neueren App-Versionen erstellt wurden
      
      var debugLevel = 0;   // 0: keine erweiterten Informationen protokollieren
                              // 1: Debug-Informationen protokollieren
      
      // ENDE --------------------------------
       
      var cloudURL;
      
      var token = "";
      var tokenRefreshTimer;
      var device = "";
      
      // ProductIDs:
      // Gruppe 1:
      // 1132174963097280512: Midas/Poolsana InverPro
      const AQUATEMP_POOLSANA="1132174963097280512";
      
      // Gruppe 2:
      // 1442284873216843776: 
      const AQUATEMP_OTHER1="1442284873216843776";
      
      var product = "";
      var reachable = false;
      
      const axios = require('axios');
      
      function setupEndpoints() {
          if(apilevel==1) {
              cloudURL = "https://cloud.linked-go.com/cloudservice/api";
          } else if(apilevel==2) {
              cloudURL = "https://cloud.linked-go.com/cloudservice/api";
          } else if(apilevel==3) {
              cloudURL = "https://cloud.linked-go.com:449/crmservice/api";
              password = require('crypto').createHash('md5').update(password).digest("hex");
          }
          printLog("API-Level " + apilevel, 1);
      }
       
      function clearValues() {
          saveValue("error", true, "boolean");
          saveValue("consumption", 0, "number");
          saveValue("state", false, "boolean");
          saveValue("rawJSON", null, "string");
      }
       
      function saveValue(key, value, sType) {
          var dp = dpRoot + "." + key;
       
          if ( !existsState(dp )) {
              printLog("Schreibe in NEUEN Datenpunkt: " + dp + " - " + value, 1);
              createState(dp,value,{name: key,  type: 'number', role: 'value'}, function () {}); 
          } else {
              printLog("Schreibe in Datenpunkt: " + dp + " - " + value, 1);
              setState(dp,value,true);
          }
      }
       
      function findCodeVal(result, code) {
          //log(code + " " + result.length);
          //log(result);
          printLog("Suche Wert " + code, 1);
          for(var i=0; i<result.length; i++) {
              //log(result[i].code);
              printLog(result[i].code, 1);
              if(result[i].code.indexOf(code) >= 0) {
                  printLog("Wert gefunden: " + result[i].value, 1);
                  return result[i].value;
              }
          }
          return "";
      }
       
      function createobjects() {
          log ("erstelle Objekte");
          createState(dpRoot + '.ambient', {read: true, write: false,  type: "number", unit:"°C", role: "value.temperature", name: "Umgebungstemperatur"});
          createState(dpRoot + '.connection', {read: true, write: false,  type: "boolean", role: "state", name: "Verbindung", def: false});
          createState(dpRoot + '.consumption', {read: true, write: false,  type: "number", unit:"W", role: "value.power", name: "Stromverbrauch", def: 0});
          createState(dpRoot + '.error', {read: true, write: false,  type: "boolean", role: "state", name: "Fehler", def: false});
          createState(dpRoot + '.errorCode', {read: true, write: false,  type: "string", name: "Fehlercode", def: ""});
          createState(dpRoot + '.errorLevel', {read: true, write: false,  type: "number", name: "Fehlerlevel"});
          createState(dpRoot + '.errorMessage', {read: true, write: false,  type: "string", name: "Fehlermeldung", def: ""});
          createState(dpRoot + '.mode', {read: true, write: true,  type: "string", states: "-1:off;0:cool;1:heat;2:auto", name: "Modus", def: ""});
          createState(dpRoot + '.rotor', {read: true, write: false,  type: "number", unit:"rpm", def: 0, name: "Lüfterdrehzahl"});
          createState(dpRoot + '.silent', {read: true, write: true,  type: "boolean", role: "state", name: "Silent", def: false});
          createState(dpRoot + '.state', {read: true, write: false,  type: "boolean", role: "state", name: "Status", def: false});
          createState(dpRoot + '.tempIn', {read: true, write: false,  type: "number", unit:"°C", role: "value.temperature", name: "Eingangstemperatur"});
          createState(dpRoot + '.tempOut', {read: true, write: false,  type: "number", unit:"°C", role: "value.temperature", name: "Ausgangstemperatur"});
          createState(dpRoot + '.tempSet', {read: true, write: true,  type: "number", unit:"°C", role: "level.temperature", name: "Solltemperatur"});
          createState(dpRoot + '.suctionTemp', {read: true, write: false,  type: "number", unit:"°C", name: "Luftansaugtemperatur"});
          createState(dpRoot + '.coilTemp', {read: true, write: false,  type: "number", unit:"°C", role: "value.temperature", name: "Kompressortemperatur"});
          createState(dpRoot + '.exhaust', {read: true, write: false,  type: "number", unit:"°C", role: "value.temperature", name: "Kompressorausgang"});
          createState(dpRoot + '.ProductCode', {read: true, write: false,  type: "string", name: "Produktcode"});
          createState(dpRoot + '.DeviceCode', {read: true, write: false,  type: "string", name: "Geräte-ID"});
          
          createState(dpRoot + '.rawJSON', {read: true, write: false,  type: "array", name: "komplette Rückgabe"});
      }
       
      function updateToken() {
       
          if(token=="") {
              printLog("Token Neuanforderung");
              var options;
              var sUrl="";
          
              if(apilevel<3) {
                  sUrl = cloudURL + '/app/user/login.json';
                  options = {
                      "user_name": username, "password": password, "type": "2"
                  };
              } else {
                  sUrl = cloudURL + '/app/user/login';
                  options = {
                      "userName": username, "password": password, "type": "2"
                  };
              }
              
      
              axios.post(sUrl, options)
      
                      .then(function (response) {
                          printLog("Login-Antwort: " + response.data);
                          if(response.status==200) {
                              if(apilevel<3) {
                                  token = response.data.object_result["x-token"];
                              } else {
                                  token = response.data.objectResult["x-token"];
                              }
                              printLog("Login ok! Token " + token);
                              //log("Token " + token);
                              updateDeviceID();
                          } else {
                              // Error!
                              printLog("Login-Fehler in updateToken(): " + response.data);
                              token = "";
                              saveValue("connection", false, "boolean");
                          }
                          })
                          .catch(function (error) {
                              // Error!
                              printLog("Login-Fehler in updateToken(): " + error);
                              token = "";
                              saveValue("connection", false, "boolean");        
                          });
          } else {
              // Token war ok
              updateDeviceID();
          }
       
          
       
          
       
      }
       
      function updateDeviceID() {
          if(token!="") {
              var sURL;
              if(apilevel<3) {
                  sURL = cloudURL + '/app/device/deviceList.json';
              } else {
                  sURL = cloudURL + '/app/device/deviceList';
              }
      
              axios.post(sURL, {
                  "productIds": [
                      "1132174963097280512",
                      "1245226668902080512",
                      "1656269521923575808", 
                      "1663080854333558784", 
                      "1596427678569979904", 
                      "1674238226096406528", 
                      "1650063968998252544", 
                      "1668781858447085568", 
                      "1186904563333062656", 
                      "1158905952238313472", 
                      "1442284873216843776", 
                      "1732565142225256450", 
                      "1548963836789501952", 
                      "1669159229372477440", 
                      "1650758828508766208", 
                      "1664085465655808000"
                      ]
              }, {
                  headers: { "x-token": token },
              })
              .then(function (response) {
                  if(response.status==200) {
                      printLog("DeviceList: " + JSON.stringify(response.data));
                      if(response.data.error_code==0) {
                          if(apilevel<3) {
                              device = response.data.object_result[0].device_code;
                              product = response.data.object_result[0].product_id;
                              reachable = (response.data.object_result[0].device_status=="ONLINE");
                          } else {
                              device = response.data.objectResult[0].deviceCode;
                              product = response.data.objectResult[0].productId;
                              reachable = (response.data.objectResult[0].deviceStatus=="ONLINE");
                          }
      
                          printLog("DeviceCode: " + device + ", ProductID: " + product + ", DeviceStatus: " + reachable);
                          saveValue("DeviceCode", device, "string");
                          saveValue("ProductCode", product, "string");
      
                          if(reachable) {
                              saveValue("connection", true, "boolean");
                              if(device!="") updateDeviceStatus(device);
                          } else {
                              // offline
                              device = "";
                              saveValue("connection", false, "boolean");
                          }
                      } else {
                          // Login-Fehler
                          log("Fehler in updateDeviceID(): " + JSON.stringify(response.data), "error");
                          token = "";
                          device = "";
                          reachable = false;
                          saveValue("connection", false, "boolean");
                      }
                  } else {
                      // Login-Fehler
                      log("Fehler in updateDeviceID(): " + JSON.stringify(response.data), "error");
                      token = "";
                      device = "";
                      reachable = false;
                      saveValue("connection", false, "boolean");
                  }
                  })
                  .catch(function (error) {
                      // Login-Fehler
                      log("Fehler in updateDeviceID(): " + error, "error");
                      token = "";
                      device = "";
                      reachable = false;
                      saveValue("connection", false, "boolean");
                  });
          }
      }
       
      function updateDeviceStatus(devicecode) {
          if(token!="") {
              var sURL="";
      
              if(apilevel<3) {
                  sURL=cloudURL + '/app/device/getDeviceStatus.json';
              } else {
                  sURL=cloudURL + '/app/device/getDeviceStatus';
              }
      
              axios.post(sURL, {
                  "device_code": devicecode,
                  "deviceCode": devicecode
              }, {
                  headers: { "x-token": token },
              })
              .then(function (response) {
                  printLog("DeviceStatus: " + response.data);
                  if(parseInt(response.data.error_code)==0) {
                      
                      if(apilevel<3) {
                          if(response.data.object_result["is_fault"]==true) {
                              // TODO: Fehlerbeschreibung abrufen
                              //clearValues();
                              saveValue("error", true, "boolean");
                              updateDeviceDetails(devicecode);
                              updateDeviceErrorMsg(devicecode);
                          } else {
                              // kein Fehler
                              saveValue("error", false, "boolean");
                              saveValue("errorMessage", "", "string");
                              saveValue("errorCode", "", "string");
                              saveValue("errorLevel", 0, "number");
                              updateDeviceDetails(devicecode);
                          }
                      } else {
                          if(response.data.objectResult["is_fault"]==true) {
                              // TODO: Fehlerbeschreibung abrufen
                              //clearValues();
                              saveValue("error", true, "boolean");
                              updateDeviceDetails(devicecode);
                              updateDeviceErrorMsg(devicecode);
                          } else {
                              // kein Fehler
                              saveValue("error", false, "boolean");
                              saveValue("errorMessage", "", "string");
                              saveValue("errorCode", "", "string");
                              saveValue("errorLevel", 0, "number");
                              updateDeviceDetails(devicecode);
                          }
                      }
                  } else {
                      log("Fehler in updateDeviceStatus(): " + JSON.stringify(response.data), "error");
                      token = "";
                      device = "";
                      reachable = false;
                      saveValue("connection", false, "boolean");
                  }
              })
              .catch(function (error) {
                  // Login-Fehler
                  log("Fehler in updateDeviceStatus(): " + error, "error");
                  token = "";
                  device = "";
                  reachable = false;
                  saveValue("connection", false, "boolean");
              });
          }
      }
       
      function updateDeviceErrorMsg(devicecode) {
          if(token!="") {
              var optionsDev;
      
              var sURL="";
      
              if(apilevel<3) {
                  sURL=cloudURL + '/app/device/getFaultDataByDeviceCode.json';
              } else {
                  sURL=cloudURL + '/app/device/getFaultDataByDeviceCode';
              }
      
              axios.post(sURL, {
                  "device_code": devicecode,
                  "deviceCode": devicecode
              }, {
                  headers: { "x-token": token },
              })
              .then(function (response) {
                 
                  if(parseInt(response.data.error_code)==0) {
       
                      
                      saveValue("error", true, "boolean");
      
                      if(apilevel<3) {
                          saveValue("errorMessage", response.data.object_result[0].description, "string");
                          saveValue("errorCode", response.data.object_result[0].fault_code, "string");
                          saveValue("errorLevel", response.data.object_result[0].error_level, "string");
                      } else {
                          saveValue("errorMessage", response.data.objectResult[0].description, "string");
                          saveValue("errorCode", response.data.objectResult[0].fault_code, "string");
                          saveValue("errorLevel", response.data.objectResult[0].error_level, "string");
                      }
                      
                      
                  } else {
                      // Login-Fehler
                      token = "";
                      device = "";
                      saveValue("connection", false, "boolean");
                  }
              })
              .catch(function (error) {
                  // Login-Fehler
                  log("Fehler in updateDeviceErrorMsg(): " + error, "error");
                  token = "";
                  device = "";
                  reachable = false;
                  saveValue("connection", false, "boolean");
              });
       
          }
      }
      
      function updateDeviceDetails(devicecode) {
          // AXIOS
          if(token!="") {
              var optionsDev;
              var sURL;
              if(apilevel<3) {
                  sURL = cloudURL + '/app/device/getDataByCode.json';
              } else {
                  sURL = cloudURL + '/app/device/getDataByCode';
              }
      
              axios.post(sURL, {
                  "device_code": devicecode,
                  "deviceCode": devicecode,
                  "protocal_codes":[
                              "Power",
                              "Mode",
                              "Manual-mute",
                              "T01",
                              "T02",
                              "2074",
                              "2075",
                              "2076",
                              "2077",
                              "H03",
                              "Set_Temp",
                              "R08",
                              "R09",
                              "R10",
                              "R11",
                              "R01",
                              "R02",
                              "R03",
                              "T03",
                              "1158",
                              "1159",
                              "F17",
                              "H02",
                              "T04",
                              "T05",
                              "T06",
                              "T07",
                              "T14",
                              "T17",
                              "T1",
                              "T2",
                              "T3",
                              "T4",
                              "T5",
                              "T6",
                              "T7"],
                  "protocalCodes":[
                              "Power",
                              "Mode",
                              "Manual-mute",
                              "T01",
                              "T02",
                              "2074",
                              "2075",
                              "2076",
                              "2077",
                              "H03",
                              "Set_Temp",
                              "R08",
                              "R09",
                              "R10",
                              "R11",
                              "R01",
                              "R02",
                              "R03",
                              "T03",
                              "1158",
                              "1159",
                              "F17",
                              "H02",
                              "T04",
                              "T05",
                              "T06",
                              "T07",
                              "T14",
                              "T17",
                              "T1",
                              "T2",
                              "T3",
                              "T4",
                              "T5",
                              "T6",
                              "T7"]
      
              }, {
                  headers: { "x-token": token },
              })
              .then(function (response) {
      //            log(response.data)
                  
                  printLog("DeviceDetails: " + response.data);
       
                  if(parseInt(response.data.error_code)==0) {
      
                      if(apilevel<3) {
                          if(debugLevel==1) saveValue("rawJSON", response.data.object_result, "string");
                          
                          if(findCodeVal(response.data.object_result, "Power")=="1") {
                              if(product==AQUATEMP_POOLSANA) {
                                  // Stromverbrauch T07 x T14 in Watt
                                  saveValue("consumption", parseFloat(findCodeVal(response.data.object_result, "T07")) * parseFloat(findCodeVal(response.data.object_result, "T14")), "number");
                                  // Luftansaug-Temperatur T01
                                  saveValue("suctionTemp", parseFloat(findCodeVal(response.data.object_result, "T01")), "number");
                                  // Inlet-Temperatur T02
                                  saveValue("tempIn", parseFloat(findCodeVal(response.data.object_result, "T02")), "number");
                                  // outlet-Temperatur T03
                                  saveValue("tempOut", parseFloat(findCodeVal(response.data.object_result, "T03")), "number");
                                  // Coil-Temperatur T04
                                  saveValue("coilTemp", parseFloat(findCodeVal(response.data.object_result, "T04")), "number");
                                  // Umgebungs-Temperatur T05
                                  saveValue("ambient", parseFloat(findCodeVal(response.data.object_result, "T05")), "number");
                                  // Kompressorausgang-Temperatur T06
                                  saveValue("exhaust", parseFloat(findCodeVal(response.data.object_result, "T06")), "number");
                              } else if (product==AQUATEMP_OTHER1) {
                                  // Stromverbrauch T7 x T14 in Watt
                                  saveValue("consumption", parseFloat(findCodeVal(response.data.object_result, "T7")) * parseFloat(findCodeVal(response.data.object_result, "T14")), "number");
                                  // Luftansaug-Temperatur T1
                                  saveValue("suctionTemp", parseFloat(findCodeVal(response.data.object_result, "T1")), "number");
                                  // Inlet-Temperatur T2
                                  saveValue("tempIn", parseFloat(findCodeVal(response.data.object_result, "T2")), "number");
                                  // outlet-Temperatur T3
                                  saveValue("tempOut", parseFloat(findCodeVal(response.data.object_result, "T3")), "number");
                                  // Coil-Temperatur T4
                                  saveValue("coilTemp", parseFloat(findCodeVal(response.data.object_result, "T4")), "number");
                                  // Umgebungs-Temperatur T5
                                  saveValue("ambient", parseFloat(findCodeVal(response.data.object_result, "T5")), "number");
                                  // Kompressorausgang-Temperatur T6
                                  saveValue("exhaust", parseFloat(findCodeVal(response.data.object_result, "T6")), "number");
                              }
                          
                              // Lüfter-Drehzahl T17
                              saveValue("rotor", parseInt(findCodeVal(response.data.object_result, "T17")), "number");
                            
                              
                          } else {
                              saveValue("consumption", 0, "number");
                              saveValue("rotor", 0, "number");
                          }
          
                          // Ziel-Temperatur Set_Temp
                          //saveValue("tempSet", parseFloat(findCodeVal(body.object_result, "Set_Temp")), "number");
      
                          // Ziel-Temperatur anhand Modus
                          if(findCodeVal(response.data.object_result,"Mode") == 1) {
                              // Heiz-Modus (-> R02)
                              saveValue("tempSet", parseFloat(findCodeVal(response.data.object_result, "R02")), "number");
                          } else if(findCodeVal(response.data.object_result,"Mode") == 0) {
                              // Kühl-Modus (-> R01)
                              saveValue("tempSet", parseFloat(findCodeVal(response.data.object_result, "R01")), "number");
                          } else if(findCodeVal(response.data.object_result,"Mode") == 2) {
                              // Auto-Modus (-> R03)
                              saveValue("tempSet", parseFloat(findCodeVal(response.data.object_result, "R03")), "number");
                          }
      
              
                          // Flüstermodus Manual-mute
                          if(findCodeVal(response.data.object_result, "Manual-mute")=="1") {
                              saveValue("silent", true, "boolean");
                          } else {
                              saveValue("silent", false, "boolean");
                          }
          
                          // Zustand Power
                          if(findCodeVal(response.data.object_result, "Power")=="1") {
                              saveValue("state", true, "boolean");
                              saveValue("mode", findCodeVal(response.data.object_result,"Mode"), "string");
                          } else {
                              saveValue("state", false, "boolean");
                              saveValue("mode", "-1", "string");
                          }
                          
                          saveValue("connection", true, "boolean");
      
                          // Durchlauf ENDE
          
                          
                      } else {
                          if(debugLevel==1) saveValue("rawJSON", response.data.objectResult, "string");
                          
                          if(findCodeVal(response.data.objectResult, "Power")=="1") {
                              if(product==AQUATEMP_POOLSANA) {
                                  // Stromverbrauch T07 x T14 in Watt
                                  saveValue("consumption", parseFloat(findCodeVal(response.data.objectResult, "T07")) * parseFloat(findCodeVal(response.data.objectResult, "T14")), "number");
                                  // Luftansaug-Temperatur T01
                                  saveValue("suctionTemp", parseFloat(findCodeVal(response.data.objectResult, "T01")), "number");
                                  // Inlet-Temperatur T02
                                  saveValue("tempIn", parseFloat(findCodeVal(response.data.objectResult, "T02")), "number");
                                  // outlet-Temperatur T03
                                  saveValue("tempOut", parseFloat(findCodeVal(response.data.objectResult, "T03")), "number");
                                  // Coil-Temperatur T04
                                  saveValue("coilTemp", parseFloat(findCodeVal(response.data.objectResult, "T04")), "number");
                                  // Umgebungs-Temperatur T05
                                  saveValue("ambient", parseFloat(findCodeVal(response.data.objectResult, "T05")), "number");
                                  // Kompressorausgang-Temperatur T06
                                  saveValue("exhaust", parseFloat(findCodeVal(response.data.objectResult, "T06")), "number");
                              } else if (product==AQUATEMP_OTHER1) {
                                  // Stromverbrauch T7 x T14 in Watt
                                  saveValue("consumption", parseFloat(findCodeVal(response.data.objectResult, "T7")) * parseFloat(findCodeVal(response.data.objectResult, "T14")), "number");
                                  // Luftansaug-Temperatur T1
                                  saveValue("suctionTemp", parseFloat(findCodeVal(response.data.objectResult, "T1")), "number");
                                  // Inlet-Temperatur T2
                                  saveValue("tempIn", parseFloat(findCodeVal(response.data.objectResult, "T2")), "number");
                                  // outlet-Temperatur T3
                                  saveValue("tempOut", parseFloat(findCodeVal(response.data.objectResult, "T3")), "number");
                                  // Coil-Temperatur T4
                                  saveValue("coilTemp", parseFloat(findCodeVal(response.data.objectResult, "T4")), "number");
                                  // Umgebungs-Temperatur T5
                                  saveValue("ambient", parseFloat(findCodeVal(response.data.objectResult, "T5")), "number");
                                  // Kompressorausgang-Temperatur T6
                                  saveValue("exhaust", parseFloat(findCodeVal(response.data.objectResult, "T6")), "number");
                              }
                          
                              // Lüfter-Drehzahl T17
                              saveValue("rotor", parseInt(findCodeVal(response.data.objectResult, "T17")), "number");
                            
                              
                          } else {
                              saveValue("consumption", 0, "number");
                              saveValue("rotor", 0, "number");
                          }
          
                          // Ziel-Temperatur Set_Temp
                          //saveValue("tempSet", parseFloat(findCodeVal(body.objectResult, "Set_Temp")), "number");
      
                          // Ziel-Temperatur anhand Modus
                          if(findCodeVal(response.data.objectResult,"Mode") == 1) {
                              // Heiz-Modus (-> R02)
                              saveValue("tempSet", parseFloat(findCodeVal(response.data.objectResult, "R02")), "number");
                          } else if(findCodeVal(response.data.objectResult,"Mode") == 0) {
                              // Kühl-Modus (-> R01)
                              saveValue("tempSet", parseFloat(findCodeVal(response.data.objectResult, "R01")), "number");
                          } else if(findCodeVal(response.data.objectResult,"Mode") == 2) {
                              // Auto-Modus (-> R03)
                              saveValue("tempSet", parseFloat(findCodeVal(response.data.objectResult, "R03")), "number");
                          }
              
                          // Flüstermodus Manual-mute
                          if(findCodeVal(response.data.objectResult, "Manual-mute")=="1") {
                              saveValue("silent", true, "boolean");
                          } else {
                              saveValue("silent", false, "boolean");
                          }
          
                          // Zustand Power
                          if(findCodeVal(response.data.objectResult, "Power")=="1") {
                              saveValue("state", true, "boolean");
                              saveValue("mode", findCodeVal(response.data.objectResult,"Mode"), "string");
                          } else {
                              saveValue("state", false, "boolean");
                              saveValue("mode", "-1", "string");
                          }
                          
                          saveValue("connection", true, "boolean");
      
                          // Durchlauf ENDE
          
                          
                      }
      
                      
                  } else {
                      // Login-Fehler
                      log("Fehler in updateDeviceDetails(): " + JSON.stringify(response.data), "error");
                      token = "";
                      device = "";
                      saveValue("connection", false, "boolean");
                  }
              })
              .catch(function (error) {
                  // Login-Fehler
                  log("Fehler in updateDeviceDetails(): " + error, "error");
                  token = "";
                  device = "";
                  reachable = false;
                  saveValue("connection", false, "boolean");
              });
                  
       
              
          }
      }
       
      function updateDevicePower(devicecode, power) {
          var powerOpt;
          var powerMode = 2;
       
          if(power==-1) {
              // aus
              powerOpt = 0;
              powerMode = -1;
          } else if(power==0) {
              // an und kühlen
              powerOpt = 1;
              powerMode = 0;
          } else if(power==1) {
              // an und heizen
              powerOpt = 1;
              powerMode = 1;
          } else if(power==2) {
              // an und auto
              powerOpt = 1;
              powerMode = 2;
          } else {
              log("ungülter Zustand!");
              return;
          }
       
          if(token!="") {
      
              var sURL="";
      
              if(apilevel<3) {
                  sURL=cloudURL + '/app/device/control.json';
              } else {
                  sURL=cloudURL + '/app/device/control';
              }
      
              axios.post(sURL, {
                  "param": [{
                      "device_code": devicecode,
                      "deviceCode": devicecode,
                      "protocol_code": "Power",
                      "protocolCode": "Power",
                      "value": powerOpt
                  }]
              }, {
                  headers: { "x-token": token },
              })
              .then(function (response) {
                  printLog("DeviceStatus: " + response.data);
                  if(parseInt(response.data.error_code)==0) {
                      
                      saveValue("mode", power.toString(), "string");
                      if(power>=0) updateDeviceMode(device, power);
                      
                  } else {
                      log("Fehler in updateDevicePower(): " + response.data, "error");
                      token = "";
                      device = "";
                      reachable = false;
                      saveValue("connection", false, "boolean");
                  }
              })
              .catch(function (error) {
                  // Login-Fehler
                  log("Fehler in updateDevicePower(): " + error, "error");
                  token = "";
                  device = "";
                  reachable = false;
                  saveValue("connection", false, "boolean");
              });
      
          }
      }
       
      function updateDeviceMode(devicecode, mode) {
          
       
          if(token!="") {
      
              var sURL="";
      
              if(apilevel<3) {
                  sURL=cloudURL + '/app/device/control.json';
              } else {
                  sURL=cloudURL + '/app/device/control';
              }
      
              axios.post(sURL, {
                  "param": [{
                      "device_code": devicecode,
                      "deviceCode": devicecode,
                      "protocol_code": "mode",
                      "protocolCode": "mode",
                      "value": mode
                  }]
              }, {
                  headers: { "x-token": token },
              })
              .then(function (response) {
                  printLog("DeviceStatus: " + response.data);
                  if(parseInt(response.data.error_code)==0) {
                      
                      saveValue("mode", mode, "string");
                      
                  } else {
                      log("Fehler in updateDeviceMode(): " + response.data, "error");
                      token = "";
                      device = "";
                      reachable = false;
                      saveValue("connection", false, "boolean");
                  }
              })
              .catch(function (error) {
                  // Login-Fehler
                  log("Fehler in updateDeviceMode(): " + error, "error");
                  token = "";
                  device = "";
                  reachable = false;
                  saveValue("connection", false, "boolean");
              });
      
          }
      }
       
      function updateDeviceSilent(devicecode, silent) {
          
          var silentMode;
       
          if(silent) {
              silentMode = "1";
          } else {
              silentMode = "0";
          }
       
          if(token!="") {
      
              var sURL="";
      
              if(apilevel<3) {
                  sURL=cloudURL + '/app/device/control.json';
              } else {
                  sURL=cloudURL + '/app/device/control';
              }
      
              axios.post(sURL, {
                  "param": [{
                      "device_code": devicecode,
                      "deviceCode": devicecode,
                      "protocol_code": "Manual-mute",
                      "protocolCode": "Manual-mute",
                      "value": silentMode
                  }]
              }, {
                  headers: { "x-token": token },
              })
              .then(function (response) {
                  printLog("DeviceStatus: " + response.data);
                  if(parseInt(response.data.error_code)==0) {
                      
                      saveValue("silent", silent, "boolean");
                      
                  } else {
                      log("Fehler in updateDeviceSilent(): " + response.data, "error");
                      token = "";
                      device = "";
                      reachable = false;
                      saveValue("connection", false, "boolean");
                  }
              })
              .catch(function (error) {
                  // Login-Fehler
                  log("Fehler in updateDeviceSilent(): " + error, "error");
                  token = "";
                  device = "";
                  reachable = false;
                  saveValue("connection", false, "boolean");
              });
      
          }
      }
       
      function updateDeviceSetTemp(devicecode, temperature) {
       
          var sTemperature = temperature.toString().replace(",", ".");
          var sMode = getState(dpRoot + ".mode").val;
          if(sMode=="-1") {
              //log("Gerät einschalten um Temperatur zu ändern!", 'warn');
              return;
          } else if(sMode=="0") {
              sMode = "R01"; // Kühlen
          } else if(sMode=="1") {
              sMode = "R02"; // Heizen
          } else if(sMode=="2") {
              sMode = "R03"; // Auto
          }
       
          
       
       
          if(token!="") {
      
              var sURL="";
      
              if(apilevel<3) {
                  sURL=cloudURL + '/app/device/control.json';
              } else {
                  sURL=cloudURL + '/app/device/control';
              }
      
              axios.post(sURL, {
                  "param": [
                      {
                      "device_code": devicecode,
                      "deviceCode": devicecode,
                      "protocol_code": "R01",
                      "protocolCode": "R01",
                      "value": sTemperature
                      },
                      {
                      "device_code": devicecode,
                      "deviceCode": devicecode,
                      "protocol_code": "R02",
                      "protocolCode": "R02",
                      "value": sTemperature
                      },
                      {
                      "device_code": devicecode,
                      "deviceCode": devicecode,
                      "protocol_code": "R03",
                      "protocolCode": "R03",
                      "value": sTemperature
                      },
                      {
                      "device_code": devicecode,
                      "deviceCode": devicecode,
                      "protocol_code": "Set_Temp",
                      "protocolCode": "Set_Temp",
                      "value": sTemperature
                      }
                      ]
              }, {
                  headers: { "x-token": token },
              })
              .then(function (response) {
                  printLog("DeviceStatus: " + response.data);
                  if(parseInt(response.data.error_code)==0) {
                      
                      saveValue("tempSet", temperature, "number");
                      
                  } else {
                      log("Fehler in updateDeviceSetTemp(): " + response.data, "error");
                      token = "";
                      device = "";
                      reachable = false;
                      saveValue("connection", false, "boolean");
                  }
              })
              .catch(function (error) {
                  // Login-Fehler
                  log("Fehler in updateDeviceSetTemp(): " + error, "error");
                  token = "";
                  device = "";
                  reachable = false;
                  saveValue("connection", false, "boolean");
              });
          }
      }
      
      function printLog(sMsg, minLevel = 1) {
          if(debugLevel>=minLevel) {
              log(sMsg);
          }
      }
      
      function productIsAquaTemp(productid) {
      
      }
       
      // Beginn des Skripts
      
      setupEndpoints();
      createobjects(); // DPs anlegen
      clearValues();
       
      updateToken(); // Zugriffstoken erfragen und aktuelle Werte lesen
       
      schedule('*/' + interval + ' * * * * *', function () {
          // regelmäßig Token und Zustand abfragen
          updateToken();
       
          // gewünschte Änderungen ausführen
          if(!getState(dpRoot + ".mode").ack) {
              updateDevicePower(device, getState(dpRoot + ".mode").val);
          }
          if(!getState(dpRoot + ".silent").ack) {
              updateDevicePower(device, getState(dpRoot + ".silent").val);
          }
      });
       
      tokenRefreshTimer = setInterval(function () {
          // Token verfällt nach 60min
          token = "";
          //log("Token nach Intervall verworfen.")
          updateToken();
      }, 3600000);
       
      on({id: dpRoot + ".mode", change: "ne", ack: false}, function (obj) {
          updateToken();
          updateDevicePower(device, getState(dpRoot + ".mode").val);
      });
       
      on({id: dpRoot + ".silent", change: "ne", ack: false}, function (obj) {
          updateToken();
          updateDeviceSilent(device, getState(dpRoot + ".silent").val);
      });
       
      on({id: dpRoot + ".tempSet", change: "ne", ack: false}, function (obj) {
          updateToken();
          updateDeviceSetTemp(device, getState(dpRoot + ".tempSet").val);
      });
      
      
      

      Getestet wurde das Skript bisher mit folgenden Wärmepumpen:
      Poolsana InverPro 21

      Andere Modelle müssten eigentlich auch funktionieren, jedoch gibt es im Skript noch einen Bug bei der Zuordnung der Werte. Schlaue Ideen sehr erwünscht 😉

      posted in Praktische Anwendungen (Showcase)
      O
      oxident
    • [Skript] Atlantic Wärmepumpe über Cozytouch abfragen

      WICHTIG: Derzeit gibt es große Probleme beim Server von Cozytouch. Ich weiß nicht, ob das Skript noch weiterentwickelt wird.
      Daher rate ich allen, sich https://github.com/tspopp/AquaMQTT anzuschauen. Ist cloudfrei und läuft super!

      Hallo!

      Ich habe eine Skript geschrieben, welches die Werte einer Atlantic / Austria Email Brauchwasserwärmepumpe abfragt. Leider habe ich keine Möglichkeit gefunden, direkt mit der Wärmepumpe zu kommunizieren (io-homecontrol -> wie Velux KLF).

      Daher klappt es nur in Verbindung mit der offiziellen Cozytouch-Bridge des Herstellers. Das Skript simuliert mehr oder weniger die App dieser Bridge.

      Leider ist das alles sehr "verwurschtelt" da die Abfrage recht komplex ist, aber ich erhalte schon brauchbare Ergebnisse.

      Bitte im nachfolgenden Skript Eure Zugangsdaten aus der App eintragen und einfach mal testen.

      Folgendes müsstet Ihr anpassen:
      username / password
      dpRoot: Hier wird der Gerätebaum erstellt
      dpSetTemp: Dies ist der DP mit dem ihr die Zieltemperatur vorgebt (also bitte selber anlegen)

      Beim ersten Aufruf wird es noch Warnungen hageln. Das legt sich dann aber.

      Da die Datenpunkte größtenteils generisch angelegt werden müsst ihr euch mal etwas durchkämpfen und brauchbare Details für euch selber herausfinden.

      Oder aber hier nachfragen 😉

      UPDATE 25.05.2024: Axios anstelle Request verwenden - dadurch keine Warnungen mehr im Log

      UPDATE 16.04.2024: Der Datenpunkt für die WW-Solltemperatur (standardmäßig 0_userdata.0.WW-Waermepumpe.WarmwasserSoll) wurde nicht angelegt.

      UPDATE 28.10.2023: Es werden jetzt manche Datenpunkte auch mit den richtigen Einheiten angelegt. Das klappt aber leider nur, wenn die Datenpunkte noch nicht vorhanden sind. Im Zweifelsfall also bitte alle DP löschen und das Skript neustarten.

      Bugs/Hinweise:

      • Der für viele sicherlich interessante Datenpunkt core:V40WaterVolumeEstimationState (geschätzter Gesamtverbrauch Warmwasser in Liter) läuft bei 65536 über, d.h. er fängt dann wieder bei 0 an. Dies kann man aber abfangen, in dem man SourceAnalytix zur Auswertung mit Reset-Erkennung verwendet.
      • Die PV-Überschussfunktion, also das manuelle Starten und Stoppen der Wärmepumpe, kann derzeit nicht via Skript gesteuert werden. Hier behelfe ich mir mit einem Shelly an dem SGReady-Kontakt. Der Heizstab kann jedoch mit dem Datenpunkt DHWBoostFull gesteuert werden.
      • Für den aktuellen Stromverbrauch sind die DP io:PowerHeatElectricalState und io:PowerHeatPumpState interessant. Sie liefern den aktuellen Verbrauch in Watt. Der DP core:ElectricEnergyConsumptionState hingegen liefert den Gesamtverbrauch in Wh.
      const dpRoot = "0_userdata.0.Atlantic";
      const dpSetTemp = "0_userdata.0.WW-Waermepumpe.WarmwasserSoll";
      const interval = 120; //sec
      
      
      const username = "eMail-Adresse";
      const password = "KENNWORT";
      
      // ------------- AB HIER NICHTS ÄNDERN ---------------- //
      // v2.0 - Migration von Request zu Axios
      // v1.0 - erstes Release
      
      const client_id = "ZThEMW5BM2h2djF0bmMxTXBvQTdHNXVENDZBYTo3aktaS1N3ZlVJNGRvaDdqRWZJVWRzR2VHNWth";
      const client_id_api = "alkxU3pBcnYwdWk3cW91OVVGTHRyOFVTNmUwYTpjWkFmYVlMNzVfYTlfcThlMGI4Unk4akU4eWdh"; // Wasserverbrauch (Token)
      const scope = "openid";
      const grant_type = "password";
      const token_url = "https://apis.groupe-atlantic.com/token";
      const jwt_url = "https://apis.groupe-atlantic.com/magellan/accounts/jwt";
      const overkiz_url = "https://ha110-1.overkiz.com/enduser-mobile-web/enduserAPI/";
      
      const atlantic_url = "https://apigam.groupe-atlantic.com:8243"; // Wasserverbrauch (über JWT)
      
      var access_token = "";
      var access_token_api = ""; // Wasserverbrauch
      var refresh_token = "";
      
      var id_token = "";
      var token_type = "";
      var expires_in = -1;
      
      var jwt = "";
      var jwt_overkiz = "";
      var session_cookie = "";
      
      var tokenRefreshTimer;
      
      var DHWP_URL = "";
      
      const axios = require('axios');
      
      function getToken() {
       
              createState(dpRoot + ".info.connection", 
                          false, 
                          {read: true, write: false,  type: "boolean", role: "indicator", def: false});
      
      
              axios.post(token_url, {
                  scope: scope,
                  username: "GA-PRIVATEPERSON/" + username,
                  password: password,
                  grant_type: grant_type
              }, {
                  headers: { 
                      "Authorization" : "Basic " + client_id,
                      "Content-Type": "application/x-www-form-urlencoded"
                      },
              })
                  .then(function (response) {
                      if(response.status==200) {
                          var jsonObject = response.data;
                          access_token = jsonObject.access_token;
                          refresh_token = jsonObject.refresh_token;
                          id_token = jsonObject.id_token;
                          expires_in = parseInt(jsonObject.expires_in);
                          session_cookie = "";
                          jwt = "";
                          //log(access_token);
                          getJWT(); // -------->
                      } else {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getToken(): " + error);
                          setState(dpRoot + ".info.connection", false, true);
                      }
                  })
                  .catch(function (error) {
                      // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getToken(): " + error);
                          setState(dpRoot + ".info.connection", false, true);
                  });
              
              
       
      }
      
      function getTokenApi() {
              // Wasserverbrauch
              axios.post(atlantic_url + "/token", {
                  grant_type: "client_credentials"
              }, {
                  headers: { 
                      "Authorization" : "Basic " +  client_id_api,
                      "Content-Type": "application/x-www-form-urlencoded"
                      },
              })
      
                  .then(function (response) {
                      if(response.status==200) {
                          var jsonObject = response.data;
                          access_token_api = jsonObject.access_token;
                          getJWTOverkiz(); // -------->
                      } else {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getTokenAPI(): " + response.status);
                          setState(dpRoot + ".info.connection", false, true);
                      }
                  })
                  .catch(function (error) {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getTokenAPI(): " + error);
                          setState(dpRoot + ".info.connection", false, true);
                  });
      }
      
      function getJWT() {
      
              axios.get(jwt_url, {
                  headers: { 
                      "Authorization" : "Bearer " + access_token,
                      "Content-Type": "application/json"
                      },
              })
      
                  .then(function (response) {
                      if(response.status==200) {
                          //log(response);
                          jwt = response.data.replace('"', '');
                          //log(jwt);
                          getSessionCookie(); // ------>
                      } else {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getJWT(): " + response.status);
                          setState(dpRoot + ".info.connection", false, true);
                      }
                  })
                  .catch(function (error) {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getJWT(): " + error);
                          setState(dpRoot + ".info.connection", false, true);
                  });
       
      }
      
      function getSessionCookie() {
              axios.post(overkiz_url + "login", {
                  'jwt': jwt
                  }, {
                  headers: { 
                      "charset": "UTF-8",
                      "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0",
                      "Content-Type": "application/x-www-form-urlencoded"
                      },
              })
      
                  .then(function (response) {
                      if(response.status==200) {
      
                          session_cookie = response.headers["set-cookie"][0];
                          //log(session_cookie);
                          session_cookie = session_cookie.substring(session_cookie.indexOf("JSESSIONID")+11);
                          session_cookie = session_cookie.substring(0, session_cookie.indexOf(";"));
      
                          
      
                          if(session_cookie!="") {
                              refreshStates(); // -------->
                          } else {
                              // Error!
                              log("Fehler bei getSessionCookie() - Cookie leer");
                              access_token = "";
                              refresh_token = "";
                              id_token = "";
                              expires_in = -1;
                              jwt = "";
                              session_cookie = "";
                          }
                          
                      } else {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getSessionCookie(): " + response.status);
                          setState(dpRoot + ".info.connection", false, true);
                      }
                  })
                  .catch(function (error) {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getSessionCookie(): " + error);
                          setState(dpRoot + ".info.connection", false, true);
                  });
          
             
              
       
      }
      
      function refreshStates() {
      
          axios.post(overkiz_url + "setup/devices/states/refresh", 
              null, 
              {
                  headers: { 
                      'Cookie': "JSESSIONID=" + session_cookie,
                      "Content-Type": "application/json",
                      "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0"
                  }
              })
      
                  .then(function (response) {
                      if(response.status==200) {
                          getSetup(); // -------->
                      } else {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getTokenAPI(): " + response.status);
                          setState(dpRoot + ".info.connection", false, true);
                      }
                  })
                  .catch(function (error) {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getTokenAPI(): " + error);
                          setState(dpRoot + ".info.connection", false, true);
                  });
      
      
          
       
      }
      
      function getSetup() {
       
              axios.get(overkiz_url + "setup", {
                  headers: { 
                      "Cookie" : "JSESSIONID=" + session_cookie,
                      "Content-Type": "application/json"
                      },
              })
      
                  .then(function (response) {
                      if(response.status==200) {
                          //log(response.data);
                          //log("getSetup ok");
                          if(getState(dpRoot + ".debug").val) setState(dpRoot + ".rawJson", response.data, true);
                          enumStates(response.data); 
                          getTokenApi(); // ------>
      
                      } else {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getSetup(): " + response.status);
                          setState(dpRoot + ".info.connection", false, true);
                      }
                  })
                  .catch(function (error) {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getSetup(): " + error);
                          setState(dpRoot + ".info.connection", false, true);
                  });
          
             
       
      }
      
      function enumStates(devTree) {
          
          
      
          for(var iDev = 0; iDev < devTree["devices"].length; iDev++) {
              
              createState(dpRoot + "." + iDev, {name: devTree["devices"][iDev].label, type: "channel"});
      
              createState(dpRoot + "." + iDev + ".enabled", 
                          devTree["devices"][iDev].enabled, 
                          {read: true, write: false,  type: "boolean", role: "state", name: devTree["devices"][iDev].label + " enabled", def: false});
              setState(dpRoot + "." + iDev + ".enabled", devTree["devices"][iDev].enabled, true);
      
              createState(dpRoot + "." + iDev + ".available", 
                          devTree["devices"][iDev].available, 
                          {read: true, write: false,  type: "boolean", role: "state", name: devTree["devices"][iDev].label + " available", def: false});
              setState(dpRoot + "." + iDev + ".available", devTree["devices"][iDev].available, true);
      
              createState(dpRoot + "." + iDev + ".oid", 
                          devTree["devices"][iDev].oid, 
                          {read: true, write: false,  type: "string", role: "state", name: devTree["devices"][iDev].label + " oid", def: ""});
              setState(dpRoot + "." + iDev + ".oid", devTree["devices"][iDev].oid, true);
      
              createState(dpRoot + "." + iDev + ".url", 
                          devTree["devices"][iDev].deviceURL, 
                          {read: true, write: false,  type: "string", role: "state", name: devTree["devices"][iDev].label + " URL", def: ""});
              setState(dpRoot + "." + iDev + ".url", devTree["devices"][iDev].deviceURL, true);
      
              createState(dpRoot + "." + iDev + ".uiClass", 
                          devTree["devices"][iDev].uiClass, 
                          {read: true, write: false,  type: "string", role: "state", name: devTree["devices"][iDev].label + " uiClass", def: ""});
              setState(dpRoot + "." + iDev + ".uiClass", devTree["devices"][iDev].uiClass, true);
      
              if(devTree["devices"][iDev].uiClass=="WaterHeatingSystem") {
                  DHWP_URL = devTree["devices"][iDev].deviceURL;
              }
      
              
              
              if (typeof devTree["devices"][iDev].states != "undefined") {
                  createState(dpRoot + "." + iDev + ".states", {type: "channel"});
      
                  for(var iDevState = 0; iDevState < devTree["devices"][iDev].states.length; iDevState++) {
      
                      if((devTree["devices"][iDev].states[iDevState].type == "1") || (devTree["devices"][iDev].states[iDevState].type == "2") || (devTree["devices"][iDev].states[iDevState].type == "3")) {
                          createDHWPstate(dpRoot + "." + iDev + ".states." + devTree["devices"][iDev].states[iDevState].name, devTree["devices"][iDev].states[iDevState].value, devTree["devices"][iDev].states[iDevState].type);
                          setState(dpRoot + "." + iDev + ".states." + devTree["devices"][iDev].states[iDevState].name, devTree["devices"][iDev].states[iDevState].value, true);
                      }
      
      
                  }
              }
              
      
          }
           setState(dpRoot + ".info.connection", true, true);
           
      }
      
      function getJWTOverkiz() {
              axios.post(overkiz_url + "enduser/jwt/createToken", 
              null, 
              {
                  headers: { 
                      'Cookie': "JSESSIONID=" + session_cookie,
                      "Content-Type": "application/json",
                      "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0"
                  }
              })
      
                  .then(function (response) {
                      if(response.status==200) {
                          jwt_overkiz = response.data.jwt;
                          if(jwt_overkiz!="") {
                              //log("jwt overkiz ok");
                              getWaterConsumption();
                              // -------->
                          } else {
                              // Error!
                              access_token = "";
                              refresh_token = "";
                              id_token = "";
                              expires_in = -1;
                              jwt = "";
                              session_cookie = "";
                              jwt_overkiz = "";
                          }
                      } else {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getJWTOverkiz(): " + response.status);
                          setState(dpRoot + ".info.connection", false, true);
                      }
                  })
                  .catch(function (error) {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getJWTOverkiz(): " + error);
                          setState(dpRoot + ".info.connection", false, true);
                  });
          
       
      }
      
      function getWaterConsumption() {
      
              axios.post(atlantic_url + "/gam/wcfservice/devicedhwrest/GetWaterConsumption", 
              {
                  'frequency': 1,
                  'deviceURL': DHWP_URL.replace("/", "\/"),
                  'jwtToken': jwt_overkiz
              }, 
              {
                  headers: { 
                      "Content-Type": "application/json",
                      "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0",
                      "Authorization" : "Bearer " + access_token_api,
                      "Locale": "de_DE",
                      //"UniqId": "648C91F2-CA6E-4870-AB47-40FF4A3C1D12",
                      "UniqId": CreateGuid(),
                      "Gfcuid": 3005,
                      "Userid": username,
                      "Platform": "ios 3.5.1 (3)"
                  }
              })
      
                  .then(function (response) {
                      if(response.status==200) {
                          createState(dpRoot + ".consumption.current", 
                              response.data.waterConsumptionDetail[response.data.waterConsumptionDetail.length-1].litersConsumed, 
                              {read: true, write: false,  type: "number", role: "state", name: " Water consumption today", unit: "l", def: 0});
                          setState(dpRoot + ".consumption.current", response.data.waterConsumptionDetail[response.data.waterConsumptionDetail.length-1].litersConsumed, true);
      
                          createState(dpRoot + ".consumption.previous", 
                              response.data.waterConsumptionDetail[response.data.waterConsumptionDetail.length-2].litersConsumed, 
                              {read: true, write: false,  type: "number", role: "state", name: " Water consumption yesterday", unit: "l", def: 0});
                          setState(dpRoot + ".consumption.previous", response.data.waterConsumptionDetail[response.data.waterConsumptionDetail.length-2].litersConsumed, true);
                              
                              if(!getState(dpSetTemp).ack) {
                                  setTemperature(getState(dpSetTemp).val);
                              }
      
                              if(!getState(dpRoot + ".DHWMode").ack) {
                                  setDHWMode();
                              }
      
      
                              if(!getState(dpRoot + ".DHWSchedule").ack) {
                                  setDHWSchedule();
                              }
      
                              if(getState(dpRoot + ".fetchHistory").val) {
                                  getHistory();
                              }
                      } else {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getWaterConsumption(): " + response.status);
                          setState(dpRoot + ".info.connection", false, true);
                      }
                  })
                  .catch(function (error) {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getWaterConsumption(): " + error);
                          setState(dpRoot + ".info.connection", false, true);
                  });
       
      }
      
      function setTemperature(setTemp) {
              axios.post(overkiz_url + "exec/apply",
                  {
                      "label" : "Cozytouch iOS: 3.5.1 (3)",
                      "actions" : [
                      {
                          "commands" : [
                              {
                              "name" : "setTargetTemperature",
                              "parameters" : [
                                  setTemp
                              ]
                              }
                          ],
                      "deviceURL" : DHWP_URL.replace("/", "\/")
                      }
                      ]
                  }, 
                  {
                      headers: { 
                          "Cookie" : "JSESSIONID=" + session_cookie,
                          "Content-Type": "application/json",
                          "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0"
                      }
                  })
          
                  .then(function (response) {
                          if(response.status==200) {
                              if(response.data.execId!="") {
                                  setState(dpSetTemp, setTemp, true);
                              } else {
                                  // Error!
                                  log("Fehler bei setTemperature()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                                  
                              }
                          } else {
                               // Error!
                                  log("Fehler bei setTemperature()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                          }
                      })
                      .catch(function (error) {
                              // Error!
                              log("Fehler bei setTemperature()");
                              access_token = "";
                              refresh_token = "";
                              id_token = "";
                              expires_in = -1;
                              jwt = "";
                              session_cookie = "";
                              jwt_overkiz = "";
                      });
      }
      
      function setDHWMode() {
       
          /*
          "autoMode",
      	"manualEcoActive",
      	"manualEcoInactive"
          */
      
          axios.post(overkiz_url + "exec/apply",
                  {
                      "label" : "Cozytouch iOS: 3.5.1 (3)",
                      "actions" : [
                      {
                          "commands" : [
                              {
                              "name" : "setDHWMode",
                              "parameters" : [
                                  getState(dpRoot + ".DHWMode").val
                              ]
                              }
                          ],
                      "deviceURL" : DHWP_URL.replace("/", "\/")
                      }
                      ]
                  }, 
                  {
                      headers: { 
                          "Cookie" : "JSESSIONID=" + session_cookie,
                          "Content-Type": "application/json",
                          "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0"
                      }
                  })
          
                  .then(function (response) {
                          if(response.status==200) {
                              if(response.data.execId!="") {
                                  setState(dpRoot + ".DHWMode", getState(dpRoot + ".DHWMode").val, true);
                              } else {
                                  // Error!
                                  log("Fehler bei setDHWMode()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                                  
                              }
                          } else {
                               // Error!
                                  log("Fehler bei setDHWMode()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                          }
                      })
                      .catch(function (error) {
                                  log("Fehler bei setDHWMode()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                      });
       
      }
      
      function setDHWSchedule() {
       
          /*
          "pac24h_elec24h",
      	"pacProg_elecProg"
          */
      
          axios.post(overkiz_url + "exec/apply",
                  {
                      "label" : "Cozytouch iOS: 3.5.1 (3)",
                      "actions" : [
                      {
                          "commands" : [
                              {
                              "name" : "setOperatingRange",
                              "parameters" : [
                                  getState(dpRoot + ".DHWSchedule").val
                              ]
                              }
                          ],
                      "deviceURL" : DHWP_URL.replace("/", "\/")
                      }
                      ]
                  }, 
                  {
                      headers: { 
                          "Cookie" : "JSESSIONID=" + session_cookie,
                          "Content-Type": "application/json",
                          "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0"
                      }
                  })
          
                  .then(function (response) {
                          if(response.status==200) {
                              if(response.data.execId!="") {
                                  setState(dpRoot + ".DHWSchedule", getState(dpRoot + ".DHWSchedule").val, true);
                              } else {
                                  // Error!
                                  log("Fehler bei setDHWSchedule()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                                  
                              }
                          } else {
                               // Error!
                                  log("Fehler bei setDHWSchedule()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                          }
                      })
                      .catch(function (error) {
                                  // Error!
                                  log("Fehler bei setDHWSchedule()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                      });
       
      }
      
      function setDHWBooster() {
      
              var boostDuration = 0;
      
              if(getState(dpRoot + ".DHWBoostFull").val) {
                  boostDuration = 2;
              }
              else {
                  setOperatingMode(false, false);
                  return; 
              }
      
              axios.post(overkiz_url + "exec/apply",
                  {
                      "label" : "Cozytouch iOS: 3.5.1 (3)",
                      "actions" : [
                      {
                          "commands" : [
                              {
                              "name" : "setBoostModeDuration",
                              "parameters" : [
                                  boostDuration
                              ]
                              }
                          ],
                      "deviceURL" : DHWP_URL.replace("/", "\/")
                      }
                      ]
                  }, 
                  {
                      headers: { 
                          "Cookie" : "JSESSIONID=" + session_cookie,
                          "Content-Type": "application/json",
                          "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0"
                      }
                  })
          
                  .then(function (response) {
                          if(response.status==200) {
                              if(response.data.execId!="") {
                                  sleep(3000);
                                  setOperatingMode(true, false);
                                  
                                  sleep(3000);
                                  refreshBooster();
                                  // -------->
                              } else {
                                  // Error!
                                  log("Fehler bei setDHWBooster()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                                  
                              }
                          } else {
                               // Error!
                                  log("Fehler bei setDHWBooster()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                          }
                      })
                      .catch(function (error) {
                                  // Error!
                                  log("Fehler bei setDHWBooster()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                      });
       
      }
      
      function refreshBooster() {
       
              
              axios.post(overkiz_url + "exec/apply",
                  {
                      "label" : "Cozytouch iOS: 3.5.1 (3)",
                      "actions" : [
                      {
                          "commands" : [
                              {
                              "name" : "refreshBoostModeDuration",
                              "parameters" : []
                              }
                          ],
                      "deviceURL" : DHWP_URL.replace("/", "\/")
                      }
                      ]
                  }, 
                  {
                      headers: { 
                          "Cookie" : "JSESSIONID=" + session_cookie,
                          "Content-Type": "application/json",
                          "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0"
                      }
                  })
      
             .then(function (response) {
                          if(response.status==200) {
                              if(response.data.execId!="") {
                                  
                                  // -------->
                              } else {
                                  // Error!
                                  log("Fehler bei refreshBooster()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                                  
                              }
                          } else {
                               // Error!
                                  log("Fehler bei refreshBooster()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                          }
                      })
                      .catch(function (error) {
                                  // Error!
                                  log("Fehler bei refreshBooster()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                      });
       
      }
      
      
      function setOperatingMode(relaunch, absence) {
       
          
              
              
              var sRelaunch;
              var sAbsence;
      
              if(relaunch) {
                  sRelaunch = "on";
              } else {
                  sRelaunch = "off";
              }
      
              if(absence) {
                  sAbsence = "on";
              } else {
                  sAbsence = "off";
              }
              
              axios.post(overkiz_url + "exec/apply",
                  {
                      "label" : "Cozytouch iOS: 3.5.1 (3)",
                      "actions" : [
                      {
                          "commands" : [
                              {
                              "name" : "setCurrentOperatingMode",
                              "parameters" : [
                                  {
                                      "relaunch": sRelaunch,
      							    "absence": sAbsence
                                  }
                              ]
                              }
                          ],
                      "deviceURL" : DHWP_URL.replace("/", "\/")
                      }
                      ]
                  }, 
                  {
                      headers: { 
                          "Cookie" : "JSESSIONID=" + session_cookie,
                          "Content-Type": "application/json",
                          "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0"
                      }
                  })
      
             .then(function (response) {
                          if(response.status==200) {
                              if(response.data.execId!="") {
                                  setState(dpRoot + ".DHWBoostFull", getState(dpRoot + ".DHWBoostFull").val, true);
                                  sleep(3000);
                                  refreshBooster();
                                  // -------->
                              } else {
                                  // Error!
                                  log("Fehler bei setOperatingMode()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                                  
                              }
                          } else {
                               // Error!
                                  log("Fehler bei setOperatingMode()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                          }
                      })
                      .catch(function (error) {
                                  // Error!
                                  log("Fehler bei setOperatingMode()");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                      });
       
      }
      
      
      function execOverkizCmd(cmd) {
       
          
              
              axios.post(overkiz_url + "exec/apply",
                  {
                      "label" : "Cozytouch iOS: 3.5.1 (3)",
                      "actions" : [
                      {
                          "commands" : [
                              {
                              "name" : cmd
                              }
                          ],
                      "deviceURL" : DHWP_URL.replace("/", "\/")
                      }
                      ]
                  }, 
                  {
                      headers: { 
                          "Cookie" : "JSESSIONID=" + session_cookie,
                          "Content-Type": "application/json",
                          "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0"
                      }
                  })
      
             .then(function (response) {
                          if(response.status==200) {
                              if(response.data.execId!="") {
                                  if(cmd=="refreshWaterConsumption") getWaterConsumption(); // ------>
                              } else {
                                  // Error!
                                  log("Fehler bei execOverkizCmd(" + cmd + ")");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                                  
                              }
                          } else {
                               // Error!
                                  log("Fehler bei execOverkizCmd(" + cmd + ")");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                          }
                      })
                      .catch(function (error) {
                                  // Error!
                                  log("Fehler bei execOverkizCmd(" + cmd + ")");
                                  access_token = "";
                                  refresh_token = "";
                                  id_token = "";
                                  expires_in = -1;
                                  jwt = "";
                                  session_cookie = "";
                                  jwt_overkiz = "";
                      });
       
      }
      
      function getHistory() {
       
              axios.get(overkiz_url + "history", {
                  headers: { 
                      "Cookie" : "JSESSIONID=" + session_cookie,
                      "Content-Type": "application/json",
                      "User-Agent": "Cozytouch/3 CFNetwork/1335.0.3 Darwin/21.6.0"
                      },
              })
      
                  .then(function (response) {
                      if(response.status==200) {
                          setState(dpRoot + ".HistoryJson", response.data, true);
                          setState(dpRoot + ".fetchHistory", false, true);
                      } else {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getHistory(): " + response.status);
                          setState(dpRoot + ".info.connection", false, true);
                      }
                  })
                  .catch(function (error) {
                          // Error!
                          access_token = "";
                          refresh_token = "";
                          id_token = "";
                          expires_in = -1;
                          jwt = "";
                          session_cookie = "";
                          log("Fehler bei getHistory(): " + error);
                          setState(dpRoot + ".info.connection", false, true);
                  });
       
      }
      
      function CreateGuid() {  
         function _p8(s) {  
            var p = (Math.random().toString(16)+"000000000").substr(2,8);  
            return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;  
         }  
         return _p8() + _p8(true) + _p8(true) + _p8();  
      }
      
      function createDHWPstate(name, value, valType) {
          var stateSuffix = "";
      
          
          // bekannte Attribute behandeln:
          if(name.endsWith("RSSILevelState")) {
              stateSuffix = "db";
          } else if (name.endsWith("TemperatureState")) {
              stateSuffix = "°C";
          } else if (name.endsWith("PowerHeatElectricalState")) {
              stateSuffix = "W";
          } else if (name.endsWith("PowerHeatPumpState")) {
              stateSuffix = "W";
          } else if (name.endsWith("V40WaterVolumeEstimationState")) {
              // Wasserbrauch insgesamt -> Überlauf bei 65536!
              stateSuffix = "l";
          }
          else if (name.endsWith("ElectricEnergyConsumptionState")) {
              // Stromverbrauch insgesamt
              stateSuffix = "Wh";
          }
      
      
          
          
      
          switch (valType) {
              case 1:
                  //console.log("1 " + name);
                  if(existsObject(name)) {
      
                  } else {
                      createState(name, value, {read: true, write: false,  type: "number", role: "state", name: name, unit: stateSuffix, def: 0});
                  }
                  break;
      
              case 2:
                  //console.log("2 " + name);
                  if(existsObject(name)) {
      
                  } else {
                      createState(name, value, {read: true, write: false,  type: "number", role: "state", name: name, unit: stateSuffix, def: 0});
                  }
                  break;
      
              case 3:
                  //console.log("3 " + name);
                  if(existsObject(name)) {
      
                  } else {
                      createState(name, value, {read: true, write: false,  type: "string", role: "state", name: name, unit: stateSuffix, def: ""});
                  }
                  break;
          }
      
      
      
      }
      
      
      // --------------------------------------------------------------
      
      createState(dpRoot + ".fetchHistory", false, {
              name: dpRoot + ".fetchHistory",
              type: 'boolean',
              role: 'state',
              desc: 'Befehlsverlauf einmalig abrufen'
          });
      
      createState(dpRoot + ".forceUpdate", false, {
              name: dpRoot + ".forceUpdate",
              type: 'boolean',
              role: 'state',
              desc: 'erzwungenes einmaliges Aktualisieren der Werte'
          });
      
      createState(dpRoot + ".HistoryJson", "", {
              name: "History (JSON)",
              type: 'string',
              role: 'state',
              desc: 'Befehlsverlauf'
          });
      
      createState(dpRoot + ".DHWMode", "", {
              name: "DHW Operating mode",
              type: 'string',
              role: 'state',
              "states": {
                  "autoMode": "Auto",
                  "manualEcoActive": "ECO aktiv",
                  "manualEcoInactive": "ECO inaktiv"
              },
              desc: 'Betriebsmodus'
          });
      
      createState(dpRoot + ".DHWSchedule", "", {
              name: "DHW Schedule",
              type: 'string',
              role: 'state',
              "states": {
                  "pacProg_elecProg": "Zeitplanung",
                  "pac24h_elec24h": "dauerhaft"
              },
              desc: 'Zeitplanung'
          });
      
      createState(dpRoot + ".DHWBoostFull", "", {
              name: "DHW Boost",
              type: 'boolean',
              role: 'state',
              desc: 'Heizstab zuschalten'
          });
      
      createState(dpRoot + ".debug", "", {
              name: "debug",
              type: 'boolean',
              role: 'state',
              desc: 'Serverantwort protokollieren'
          });
      
      createState(dpRoot + ".rawJSON", "", {
              name: "rawJSON",
              type: 'string',
              role: 'state',
              desc: 'Serverantwort'
          });
      
      createState(dpSetTemp, "", {
              name: "WW-Solltemperatur",
              type: 'number',
              role: 'state',
              unit: '°C',
              desc: 'Solltemperatur der Wärmepumpe'
          });
      
      setState(dpSetTemp, getState(dpSetTemp), true);
      
      getToken();
      
      tokenRefreshTimer = setInterval(async function () {
          // Token verfällt nach 60min
          access_token = "";
          access_token_api = "";
      
          refresh_token = "";
          id_token = "";
          expires_in = -1;
          jwt = "";
          jwt_overkiz = "";
          session_cookie = "";
      
          //log("Token nach Intervall verworfen.")
          getToken();
      }, 600000);
      
      schedule('*/' + interval + ' * * * * *', function () {
          // regelmäßig Token und Zustand abfragen
          // access_token = ""; // Workaround...
          
          if(access_token != "") {
              getJWT();
          } else {
              getToken();
          }
          
      });
      
      on({id: dpRoot + ".fetchHistory", change: 'ne'}, function(obj) {
          if(getState(dpRoot + ".fetchHistory").val) {
              if(session_cookie != "") {
                  getHistory();
              }
          }
      });
      
      on({id: dpRoot + ".forceUpdate", change: 'ne'}, function(obj) {
          if(getState(dpRoot + ".forceUpdate").val) {
              if(session_cookie != "") {
                  execOverkizCmd("refreshMiddleWaterTemperature");
                  execOverkizCmd("refreshDHWCapacity");
                  execOverkizCmd("refreshWaterConsumption");
                  
      
                  setState(dpRoot + ".forceUpdate", false);
              }
          }
      });
      
      on({id: dpRoot + ".DHWMode", change: 'ne', ack: false}, function(obj) {
          
              if(session_cookie != "") {
                  setDHWMode();
              }
          
          
      });
      
      on({id: dpRoot + ".DHWSchedule", change: 'ne', ack: false}, function(obj) {
          
              if(session_cookie != "") {
                  setDHWSchedule();
              }
          
          
      });
      
      on({id: dpRoot + ".DHWBoostFull", change: 'ne', ack: false}, function(obj) {
          
              if(session_cookie != "") {
                  setDHWBooster();
              }
          
          
      });
      
      posted in JavaScript
      O
      oxident
    • RE: [Neuer Adapter] Senec Home Adapter

      @homoran Okay, das ist natürlich ein Problem. Ich gehe da vermutlich zu "blauäugig" ran und installier die selber. Jedoch parallel zum Senec und Fronius-WR. Also quasi nur AC-seitig.

      Vielleicht finde ich später mal einen Installateur, der das dann abnickt oder verbessert. Aber meine Erfahrungen mit den Senec-Installateuren haben mir gezeigt, dass gestresste (Subunternehmer-)Elektriker leider auch nicht besser sind als mein gefährliches Halbwissen 😉

      posted in Entwicklung
      O
      oxident
    • RE: Mit Traccar eine geofence Alternative für Iphone und Android

      @braindead Habe Deinen POC einfach mal ausprobiert und muss sagen, er läuft jetzt seit einigen Tagen völlig perfekt. Es gibt keinerlei Probleme und er macht auch schon fast alles, was man sich wünschen kann.

      Ich weiß jetzt nicht, wie und ob Du damit eine Testphase bzw. sogar perspektivisch ein Stable-Release anstrebst, aber wenn ich helfen kann, dann gerne!

      Von meiner (User-)Seite gäbe es eigentlich nur eine kleine Sache:

      Man könnte die Websocket-API anstelle des festen Pollings nutzen. Das würde aber einen Session-Cookie und eventuell doch recht grundlegende Code-Anpassungen erfordern.

      posted in Praktische Anwendungen (Showcase)
      O
      oxident
    • RE: Test Adapter Growatt v3.3.1

      Prima Arbeit, bin schwer begeistert.
      Wie schon im anderen Thread geschrieben benutze ich den Adapter seit v0.0.6 (mittlerweile v0.0.9) absolut erfolgreich an meinem Balkonkraftwerk (Growatt 1300-S mit ShineWIFI-S).
      Die Daten kommen alle zuverlässig und ordentlich benannt an.

      Wäre toll, wenn es der Adapter in den Stable-Branch schafft!

      posted in Tester
      O
      oxident
    • RE: E-INK Display OpenEPaperLink - Displayanzeige mit Batterie

      Alles klar, habe es jetzt mal selber "gefrickelt". Hierzu habe ich im Vis eine View erstellt und mir dort als Hilfsmittel einen 296x128px Rahmen gezogen. Außerdem habe ich den Adapter "Puppeteer" installiert.

      Im Vis tobe ich mich dann innerhalb des Rahmens aus und nutze folgendes Javascript:

      sendTo('puppeteer.0', 'screenshot', { 
          url: 'http://localhost:8082/vis/index.html#NAME_DER_VIEW',
          ioBrokerOptions: {
              storagePath: 'test.jpg',
            },
            waitOption: {
              waitForTimeout: 5000,
            },
            viewportOptions: {
              width: 296,
              height: 128
            },
            type: "jpeg",
            quality: 100
      }, obj => {
            if (obj.error) {
              log(`Error taking screenshot: ${obj.error.message}`, 'error');
            } else {
              log('Sucessfully took screenshot');
              sendImageToEPaper(obj.result, "MAC-VOM-DISPLAY");
            }
      });
      
      function sendImageToEPaper(objImage, sMac) {
          var request = require('request');
          var options = {
                  url: 'http://IP-VOM-AP/imgupload',
                  method: 'POST',
                  formData: { 
                      "dither": "0", 
                      "mac": sMac,
                      "image": objImage },
                  
              };
              
          request(options,function (error, response, body){
              
                  //log("Login-Antwort: " + JSON.stringify(response));
                  if(parseInt(body.error_code)==0) {
                      
                  } else {
                      
                  }
                  
              });
      }
      
      posted in Praktische Anwendungen (Showcase)
      O
      oxident
    • RE: Beta Test js-controller Kiera (v6.0)

      @diamand2k22 Bin der, der sich für https://github.com/kopierschnitte/ioBroker.blueconnect verantwortlich fühlt. War eigentlich nur eine Bugfix-Übernahme des eigentlichen Erstellers. Aber der Adapter läuft bisher ohne Probleme.

      Leider fehlt mir die Ahnung und auch ein wenig die Zeit, das bei Github ordentlich zu pflegen. Daher auch die fehlende Liebe, die @Thomas-Braun korrekt angemerkt hat.

      Wie auch immer, bitte mal testen, ob der Fork unter https://github.com/kopierschnitte/ioBroker.blueconnect funktioniert.

      posted in Tester
      O
      oxident
    • RE: E-INK Display OpenEPaperLink - Displayanzeige mit Batterie

      Ich muss aber einwerfen, dass Pupeteer irgendwie derzeit noch nicht rund läuft. Habe nach einem iobroker-Umzug derzeit Probleme, den Adapter wieder lauffähig zu bekommen.

      Wenn das geklärt ist mache ich gerne eine Schritt für Schritt Anleitung.

      Andererseits fände ich diese Funktionalität eigentlich sehr gut im OpenEPaperLink-Adapter aufgehoben. Was denkt ihr?

      posted in Praktische Anwendungen (Showcase)
      O
      oxident
    • RE: Test Adapter Samsung Smartthings v.0.0.x

      Ich denke, das Problem ist hier, dass es halt ein "generischer" Adapter ist. Bei dem riesigen Zoo an Geräten im Samsung-Universum wäre es auch unmöglich, hier seitens der Entwickler alle Sonderlocken abzubilden.

      Schuld dürfte jedoch eher Samsung haben.

      Daher auch mein Rat: Selektiv schauen, was überhaupt benötigt wird und den Rest dann ausfiltern. Ja, das ist komplex. Glaubt mir, mit einem Samsung Familyhub Kühlschrank weiß ich, wovon ich rede 😞

      posted in Tester
      O
      oxident
    • RE: E-INK Display OpenEPaperLink - Displayanzeige mit Batterie

      @beowolf Dann ist etwas Handarbeit gefragt. Schau mal mein Issue (mit Workaround):

      https://github.com/foxriver76/ioBroker.puppeteer/issues/13

      kopierschnitte created this issue in foxriver76/ioBroker.puppeteer

      closed Installation/Usage not possible on ARM64 platforms (RPi, etc.) #13

      posted in Praktische Anwendungen (Showcase)
      O
      oxident

    Latest posts made by oxident

    • RE: Test Adapter Grünbeck v0.0.x

      Habe mir mittlerweile mit der Integration von Home Assistant geholfen. Das klappt dort eigentlich recht zuverlässig.
      Hole mir die Daten dann einfach über den HASS-Adapter in den iobroker.

      Das Grünbeck das auf den Keks geht ist schon klar, aber sorry, die sind ja auch selber Schuld. Sie haben doch extra einen zweiten Netzwerkport vorgesehen und die Kommunikation zur Azure-Cloud läuft eh schon via MQTT. Wenn man den Server einfach "umbiegen" könnte, dann wäre Ruhe bei denen und wir alle happy 😞

      Aber Stand der Dinge ist ja wohl, dass der zus. Netzwerkport tot bleibt und keinerlei Support von Seiten Grünbecks mehr zu erwarten ist. Dessen sollte sich jeder bewusst sein, der eine Kaufentscheidung treffen möchte.

      posted in Tester
      O
      oxident
    • RE: Passwort pro App

      Bei der Nutzung von "Url" sieht es leider genauso aus. Nutze iobroker hinter nginx auf einem Samsung mit Android 16. Bis zum Update alles super, seitdem "Bitte Zugangsdaten überprüfen".

      Im lokalen Netz (mit lokaler Url) und gleichen Zugangsdaten alles schick. Keine Meldungen im iob-Log.

      posted in Visualisierung
      O
      oxident
    • RE: adapter-core unterschiedlich (3.3.1 / 3.3.2)

      Huch, was hab ich denn jetzt losgetreten 😉
      Dann lass ich das mal offen. Bei mir klappen ja alle Adapter noch, aber ich verstehe das Problem.

      Also bitte nicht nachmachen!!

      @ticaki Trotzdem danke, dass Du Dich da reingelesen hast und, zumindest für mich, einen Workaround gefunden hast.

      posted in ioBroker Allgemein
      O
      oxident
    • RE: adapter-core unterschiedlich (3.3.1 / 3.3.2)

      @ticaki said in adapter-core unterschiedlich (3.3.1 / 3.3.2):

      @oxident
      hab das Problem gefunden.

      in /opt/iobroker/package.json steht am ende

      ,
        "overrides": {
          "@iobroker/adapter-core": "^3.2.1"
        }
      

      das kann komplett weg - auch das komma

      Adapter deinstallieren - dann package-lock.json löschen - dann adapter installieren. Jetzt sollte es gehen.

      Wow, genial. Hab ich auch überlesen.

      Vielen Dank!!

      posted in ioBroker Allgemein
      O
      oxident
    • RE: adapter-core unterschiedlich (3.3.1 / 3.3.2)

      @ticaki Ja, ich finde es ja auch komisch. Vorallem verstehe ich nicht, wieso npm show meint, die 3.3.2 wäre installiert.
      Selbst wenn ich mir den Inhalt der adapter-core Dateien händisch anschaue (sowohl package.json, als auch die Quelldateien), so ist es auch tatsächlich nur die Version 3.3.1.

      Wisst ihr, woher npm show ... version seine Daten bezieht?

      posted in ioBroker Allgemein
      O
      oxident
    • RE: adapter-core unterschiedlich (3.3.1 / 3.3.2)

      @ticaki said in adapter-core unterschiedlich (3.3.1 / 3.3.2):

      Ich gehe mal davon aus, das in der installierte package-json auch das ^ davor ist.

      Also in der vom Unifi-Network-Adapter ist (korrekterweise) die 3.3.2 als Minimum angegeben. Zumindest verstehe ich das so:

       "dependencies": {
          "@iobroker/adapter-core": "^3.3.2",
      
      posted in ioBroker Allgemein
      O
      oxident
    • RE: adapter-core unterschiedlich (3.3.1 / 3.3.2)

      @ticaki said in adapter-core unterschiedlich (3.3.1 / 3.3.2):

      @oxident

      wegen dem ^ davor - die adapter-core Version dürfte nicht das problem sein.

      "@iobroker/adapter-core": "^3.3.1",
      

      Aber ein wesentlicher Fix in der Version 3.3.2 ist doch exakt der mit dem TokenRefresher:
      https://github.com/ioBroker/adapter-core/issues/619

      Oder stehe ich auf dem Schlauch?

      bolliy created this issue in ioBroker/adapter-core

      closed Cannot find module esm/TokenRefresher #619

      posted in ioBroker Allgemein
      O
      oxident
    • RE: adapter-core unterschiedlich (3.3.1 / 3.3.2)

      @thomas-braun
      Hat leider nichts gebracht:

      NPM version: 10.9.3
      Installing iobroker.unifi-network@1.1.6... (System call)
      
      added 5 packages in 10s
      
      459 packages are looking for funding
        run `npm fund` for details
      host.iobroker install adapter unifi-network
      upload [19] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/clients.jsonConfig.json clients.jsonConfig.json application/json
      upload [18] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/devices.jsonConfig.json devices.jsonConfig.json application/json
      upload [17] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/expert.jsonConfig.json expert.jsonConfig.json application/json
      upload [16] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/firewall.jsonConfig.json firewall.jsonConfig.json application/json
      upload [15] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/general.jsonConfig.json general.jsonConfig.json application/json
      upload [14] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/de.json i18n/de.json application/json
      upload [13] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/en.json i18n/en.json application/json
      upload [12] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/es.json i18n/es.json application/json
      upload [11] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/fr.json i18n/fr.json application/json
      upload [10] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/it.json i18n/it.json application/json
      upload [9] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/nl.json i18n/nl.json application/json
      upload [8] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/pl.json i18n/pl.json application/json
      upload [7] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/pt.json i18n/pt.json application/json
      upload [6] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/ru.json i18n/ru.json application/json
      upload [5] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/uk.json i18n/uk.json application/json
      upload [4] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/i18n/zh-cn.json i18n/zh-cn.json application/json
      upload [3] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/jsonConfig.json jsonConfig.json application/json
      upload [2] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/lan.jsonConfig.json lan.jsonConfig.json application/json
      upload [1] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/unifi-network.png unifi-network.png image/png
      upload [0] unifi-network.admin /opt/iobroker/node_modules/iobroker.unifi-network/admin/wlan.jsonConfig.json wlan.jsonConfig.json application/json
       empty object!
      host.iobroker object system.adapter.unifi-network created/updated
      Updating objects from io-package.json for adapter "unifi-network" with version "1.1.6"
       empty object!
       empty object!
      host.iobroker create instance unifi-network
      host.iobroker object system.adapter.unifi-network.0.alive created
      host.iobroker object system.adapter.unifi-network.0.connected created
      host.iobroker object system.adapter.unifi-network.0.compactMode created
      host.iobroker object system.adapter.unifi-network.0.cpu created
      host.iobroker object system.adapter.unifi-network.0.cputime created
      host.iobroker object system.adapter.unifi-network.0.memHeapUsed created
      host.iobroker object system.adapter.unifi-network.0.memHeapTotal created
      host.iobroker object system.adapter.unifi-network.0.memRss created
      host.iobroker object system.adapter.unifi-network.0.uptime created
      host.iobroker object system.adapter.unifi-network.0.inputCount created
      host.iobroker object system.adapter.unifi-network.0.outputCount created
      host.iobroker object system.adapter.unifi-network.0.eventLoopLag created
      host.iobroker object system.adapter.unifi-network.0.sigKill created
      host.iobroker object system.adapter.unifi-network.0.logLevel created
      host.iobroker object unifi-network.0.info created
      host.iobroker object unifi-network.0.info.connection created
      host.iobroker object unifi-network.0.info.lastRealTimeData created
      host.iobroker Set default value of unifi-network.0.info.connection: false
      host.iobroker object system.adapter.unifi-network.0 created
      
      /opt/iobroker$ npm show @iobroker/adapter-core version
      3.3.2
      
      +-- iobroker.unifi-network@1.1.6
      | `-- @iobroker/adapter-core@3.3.1 deduped
      

      Letzteres steht übrigens bei allen anderen Adaptern auch. Wie gesagt, in der package.json von adapter-core ist auch definitiv Version 3.3.1 angegeben. Keine Ahnung, wieso npm show "denkt", es wäre schon die 3.3.2

      posted in ioBroker Allgemein
      O
      oxident
    • RE: adapter-core unterschiedlich (3.3.1 / 3.3.2)

      @thomas-braun
      Den hier:
      https://github.com/Scrounger/ioBroker.unifi-network
      Installiert hab ich die Latest (1.1.6) via Github.

      posted in ioBroker Allgemein
      O
      oxident
    • adapter-core unterschiedlich (3.3.1 / 3.3.2)

      Hallo!

      Ich wollte gerade den neuen Unifi-Adapter von scrounger testen und scheitere an der Abhängigkeit adapter-core->TokenRefresher.
      Das eigentliche Problem scheint zu sein, dass der Befehl

      cd /opt/iobroker
      npm show @iobroker/adapter-core version
      

      Version 3.3.2 liefert, die Ausgabe von

      cat /opt/iobroker/node_modules/@iobroker/adapter-core/package.json
      

      jedoch die ältere 3.3.1, welche ja genau dieses Problem mit TokenRefresher hat, zeigt:

      {
      "name": "@iobroker/adapter-core",
      "version": "3.3.1",
      "description": "Core module to be used in ioBroker adapters. Acts as the bridge to js-controller.",
      "engines": {
      "node": ">=16"
      },
      

      Ich möchte ungern jetzt einfach so mit NPM rumwurschteln ... das geht sicher schief. Habt Ihr eine Idee, was da los sein könnte?

      JS-Controller 7.0.7
      NPM 10.9.3
      NodeJS 22.20.0

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