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

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

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. setState's in Funktionen

NEWS

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    11
    1
    486

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    24
    1
    1.6k

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

setState's in Funktionen

Geplant Angeheftet Gesperrt Verschoben JavaScript
javascript
16 Beiträge 2 Kommentatoren 1.8k Aufrufe 3 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • hanssH hanss

    @alcalzone
    Das wäre ja einfach, werde ich gleich einmal ausprobieren.
    Vielen Dank

    leider macht er mir die rote Fehlerlinie unter den 3 await??

    async function evohome_IF(){
        const EvohomeClient = require('evohome').EvohomeClient
        const HeatSetpointStatus = require('evohome').HeatSetpointStatus
        const username = 'xxxxxxxxxxxx'
        const password = 'yyyyyyyyyyyy'
        const evohomeClient = new EvohomeClient(username, password)
    
        evohomeClient.getLocationsWithAutoLogin(300).then(locations => {      // (x) = Session Abbruch nach x Sekunden
        // log('JSON OBJ: '+JSON.stringify(locations))
     
        S_Raum.forEach(function(element, index){            // z.Zt. 8 Räume 0-7
            const deviceId = locations[0].devices[index].deviceID   
            var Raum_name = locations[0].devices[index].name
            var Rindex = S_Raum.indexOf(Raum_name)               // suchen Raumname in S_Raum Array
            if (Rindex != -1) {
                var IstTemp = locations[0].devices[index].thermostat.indoorTemperature
                var SollTemp = locations[0].devices[index].thermostat.changeableValues.heatSetpoint.value   
                // log(Rindex+'-Zimmer: '+Raum_name+'  Temperatur: '+IstTemp+'  Soll Temp: '+SollTemp)
                
                SollTemp = Absenkung(deviceId,Rindex,SollTemp,evohomeClient,HeatSetpointStatus)
    
                await setStateAsync(Out_Root+D_Raum[Rindex]+".Temperatur",IstTemp)
                await setStateAsync(Out_Root+D_Raum[Rindex]+".Soll",SollTemp)    
                await setStateAsync(Out_Root+D_Raum[Rindex]+".evoDeviceID",deviceId)
    
                // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Hold, 15)           // Wohnzimmer Temp. setzen
                // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Temporary, 15,10)   // Wohnzimmer auf 15° 30 min. lang
                // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Scheduled)     // Wohnzimmer auf Zeitplan zurücksetzen
            } else {
                logerror('Raum '+Raum_name+' nicht gefunden')
            }
        }) // forEach
        }).catch(err => {
            log('Fehler bei EvoHome Abfrage: '+ err)
            // process.exit(3)
        })
    } // evohome_IF
    
    AlCalzoneA Offline
    AlCalzoneA Offline
    AlCalzone
    Developer
    schrieb am zuletzt editiert von AlCalzone
    #4

    @hanss Die enthaltende Funktion muss als async deklariert sein. Das beißt sich aber auch meit deinem .forEach, welches du am besten gegen eine for-Schleife ersetzt. Ich hab hier nur die minimal nötige Änderung gemacht - so richtig erschließt sich mir dein Umgang mit dem Array nicht (Iteration durch eins, Zugriff auf ein anderes) 😅:

    
    async function evohome_IF(){
        const EvohomeClient = require('evohome').EvohomeClient
        const HeatSetpointStatus = require('evohome').HeatSetpointStatus
        const username = 'USERNAME'
        const password = 'PASSWORT'
        const evohomeClient = new EvohomeClient(username, password)
     
        evohomeClient.getLocationsWithAutoLogin(300).then(locations => {      // (x) = Session Abbruch nach x Sekunden
        // log('JSON OBJ: '+JSON.stringify(locations))
     
       // Durch Array iterieren, im Kontext der aktuellen Funktion
       for (let index = 0; index < S_Raum.length; index++) {            // z.Zt. 8 Räume 0-7
            const deviceId = locations[0].devices[index].deviceID   
            var Raum_name = locations[0].devices[index].name
            var Rindex = S_Raum.indexOf(Raum_name)               // suchen Raumname in S_Raum Array
            if (Rindex != -1) {
                var IstTemp = locations[0].devices[index].thermostat.indoorTemperature
                var SollTemp = locations[0].devices[index].thermostat.changeableValues.heatSetpoint.value   
                // log(Rindex+'-Zimmer: '+Raum_name+'  Temperatur: '+IstTemp+'  Soll Temp: '+SollTemp)
                
                SollTemp = Absenkung(deviceId,Rindex,SollTemp,evohomeClient,HeatSetpointStatus)
     
                await setStateAsync(Out_Root+D_Raum[Rindex]+".Temperatur",IstTemp)
                await setStateAsync(Out_Root+D_Raum[Rindex]+".Soll",SollTemp)    
                await setStateAsync(Out_Root+D_Raum[Rindex]+".evoDeviceID",deviceId)
     
                // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Hold, 15)           // Wohnzimmer Temp. setzen
                // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Temporary, 15,10)   // Wohnzimmer auf 15° 30 min. lang
                // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Scheduled)     // Wohnzimmer auf Zeitplan zurücksetzen
            } else {
                logerror('Raum '+Raum_name+' nicht gefunden')
            }
        } // for
        }).catch(err => {
            log('Fehler bei EvoHome Abfrage: '+ err)
            // process.exit(3)
        })
    } // evohome_IF
    

    Hier noch etwas Background zum nachlesen:
    https://gist.github.com/AlCalzone/d14b854b69ce5e8a03718336cc650a95#

    Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

    hanssH 2 Antworten Letzte Antwort
    0
    • AlCalzoneA AlCalzone

      @hanss Die enthaltende Funktion muss als async deklariert sein. Das beißt sich aber auch meit deinem .forEach, welches du am besten gegen eine for-Schleife ersetzt. Ich hab hier nur die minimal nötige Änderung gemacht - so richtig erschließt sich mir dein Umgang mit dem Array nicht (Iteration durch eins, Zugriff auf ein anderes) 😅:

      
      async function evohome_IF(){
          const EvohomeClient = require('evohome').EvohomeClient
          const HeatSetpointStatus = require('evohome').HeatSetpointStatus
          const username = 'USERNAME'
          const password = 'PASSWORT'
          const evohomeClient = new EvohomeClient(username, password)
       
          evohomeClient.getLocationsWithAutoLogin(300).then(locations => {      // (x) = Session Abbruch nach x Sekunden
          // log('JSON OBJ: '+JSON.stringify(locations))
       
         // Durch Array iterieren, im Kontext der aktuellen Funktion
         for (let index = 0; index < S_Raum.length; index++) {            // z.Zt. 8 Räume 0-7
              const deviceId = locations[0].devices[index].deviceID   
              var Raum_name = locations[0].devices[index].name
              var Rindex = S_Raum.indexOf(Raum_name)               // suchen Raumname in S_Raum Array
              if (Rindex != -1) {
                  var IstTemp = locations[0].devices[index].thermostat.indoorTemperature
                  var SollTemp = locations[0].devices[index].thermostat.changeableValues.heatSetpoint.value   
                  // log(Rindex+'-Zimmer: '+Raum_name+'  Temperatur: '+IstTemp+'  Soll Temp: '+SollTemp)
                  
                  SollTemp = Absenkung(deviceId,Rindex,SollTemp,evohomeClient,HeatSetpointStatus)
       
                  await setStateAsync(Out_Root+D_Raum[Rindex]+".Temperatur",IstTemp)
                  await setStateAsync(Out_Root+D_Raum[Rindex]+".Soll",SollTemp)    
                  await setStateAsync(Out_Root+D_Raum[Rindex]+".evoDeviceID",deviceId)
       
                  // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Hold, 15)           // Wohnzimmer Temp. setzen
                  // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Temporary, 15,10)   // Wohnzimmer auf 15° 30 min. lang
                  // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Scheduled)     // Wohnzimmer auf Zeitplan zurücksetzen
              } else {
                  logerror('Raum '+Raum_name+' nicht gefunden')
              }
          } // for
          }).catch(err => {
              log('Fehler bei EvoHome Abfrage: '+ err)
              // process.exit(3)
          })
      } // evohome_IF
      

      Hier noch etwas Background zum nachlesen:
      https://gist.github.com/AlCalzone/d14b854b69ce5e8a03718336cc650a95#

      hanssH Offline
      hanssH Offline
      hanss
      schrieb am zuletzt editiert von hanss
      #5

      @alcalzone

      leider macht er die rote Fehlerlinie unter den 3 await's auch wenn .forEach durch for-next ersetzt wird.
      Wenn 'for-next' und 'evohomeClient.getLocationsWithAutoLogin(300).then(locations => {'
      entfernt wird, dann verschwindet auch die rote Fehlerlinie.
      Ist anscheinend doch nicht so einfach.

      AlCalzoneA 1 Antwort Letzte Antwort
      0
      • hanssH hanss

        @alcalzone

        leider macht er die rote Fehlerlinie unter den 3 await's auch wenn .forEach durch for-next ersetzt wird.
        Wenn 'for-next' und 'evohomeClient.getLocationsWithAutoLogin(300).then(locations => {'
        entfernt wird, dann verschwindet auch die rote Fehlerlinie.
        Ist anscheinend doch nicht so einfach.

        AlCalzoneA Offline
        AlCalzoneA Offline
        AlCalzone
        Developer
        schrieb am zuletzt editiert von
        #6

        @hanss Whoops, den Mix aus Promises und async-Funktion hab ich übersehen.

        Entweder du änderst Zeile 8 zu

        evohomeClient.getLocationsWithAutoLogin(300).then(async (locations) => {
        

        oder du machst es gleich richtig mit await:

        const locations = await evohomeClient.getLocationsWithAutoLogin(300);
        

        --> in jedem Fall mal den Link lesen ;)

        Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

        hanssH 1 Antwort Letzte Antwort
        0
        • AlCalzoneA AlCalzone

          @hanss Whoops, den Mix aus Promises und async-Funktion hab ich übersehen.

          Entweder du änderst Zeile 8 zu

          evohomeClient.getLocationsWithAutoLogin(300).then(async (locations) => {
          

          oder du machst es gleich richtig mit await:

          const locations = await evohomeClient.getLocationsWithAutoLogin(300);
          

          --> in jedem Fall mal den Link lesen ;)

          hanssH Offline
          hanssH Offline
          hanss
          schrieb am zuletzt editiert von
          #7

          @alcalzone
          Das war es leider auch nicht.
          Ist scheinbar doch recht kompliziert mit async.
          Ich glaube, ich verwende weiterhin ein setTimeout(function (){})
          Vielen Dank.

          AlCalzoneA 1 Antwort Letzte Antwort
          0
          • hanssH hanss

            @alcalzone
            Das war es leider auch nicht.
            Ist scheinbar doch recht kompliziert mit async.
            Ich glaube, ich verwende weiterhin ein setTimeout(function (){})
            Vielen Dank.

            AlCalzoneA Offline
            AlCalzoneA Offline
            AlCalzone
            Developer
            schrieb am zuletzt editiert von
            #8

            @hanss

            Ist scheinbar doch recht kompliziert mit async.

            Eigentlich nicht... Es gibt 2 Regeln:

            1. Diejenige Funktion, die das await unmittelbar umschließt, muss async sein.
            2. Wenn du auf den Abschluss einer solchen Funktion warten willst, um den folgenden Code auszuführen, musst du await vor den Aufruf setzen. Dazu siehe 1. - das setzt sich nach oben fort.

            Schwieriger wird es nur, wenn du Sonderlocken ala .forEach statt Basis-Sprachfeatures wie for-Schleifen nutzt.

            Ich glaube, ich verwende weiterhin ein setTimeout(function (){})

            Du glaubst? Nichtsdestotrotz, wenn in diesem Timeout ein await genutzt werden soll, muss es
            setTimeout(async function (){}) lauten

            Vielleicht rückst du mal mit dem gesamten Code raus, statt nur mit Schnipseln ;)

            Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

            hanssH 1 Antwort Letzte Antwort
            0
            • AlCalzoneA AlCalzone

              @hanss

              Ist scheinbar doch recht kompliziert mit async.

              Eigentlich nicht... Es gibt 2 Regeln:

              1. Diejenige Funktion, die das await unmittelbar umschließt, muss async sein.
              2. Wenn du auf den Abschluss einer solchen Funktion warten willst, um den folgenden Code auszuführen, musst du await vor den Aufruf setzen. Dazu siehe 1. - das setzt sich nach oben fort.

              Schwieriger wird es nur, wenn du Sonderlocken ala .forEach statt Basis-Sprachfeatures wie for-Schleifen nutzt.

              Ich glaube, ich verwende weiterhin ein setTimeout(function (){})

              Du glaubst? Nichtsdestotrotz, wenn in diesem Timeout ein await genutzt werden soll, muss es
              setTimeout(async function (){}) lauten

              Vielleicht rückst du mal mit dem gesamten Code raus, statt nur mit Schnipseln ;)

              hanssH Offline
              hanssH Offline
              hanss
              schrieb am zuletzt editiert von hanss
              #9

              @alcalzone

              Bitte, wenn Du dir das antun möchtest - ist recht umfangreich.

              Inzwischen denke ich, dass es besser wäre, statt mit dem festen Timeout
              setTimeout(function () {
              darauf zu warten, bis die funktion evohome_IF() komplett fertig ist.
              Der komplette Code ist weiter unten.
              Danke.

              function RaumAbw(obj) {
                  let Startzeit = getState(Out_Root+D_Raum[0]+".Soll").ts
                    evohome_IF()                             // Ist- und Solltemperaturen abrufen, Absenkung prüfen
                  let Endtzeit = getState(Out_Root+D_Raum[0]+".Soll").ts
                  log('evohome_IF() Funktion Dauer: '+(Endtzeit-Startzeit)+' ms.')
                  
                  RTdiff =  0;
                  TempDiff_Sum = 0;
                  MaxTempRaum = ""
                  RTdiff_max = 0
                  maxSollTemp = 0
                  Heizleistung_Soll = 0
                  var LastTS = Date.now()
                  var SollTemp = 0, IstTemp = 0
                  setTimeout(function () {                            // 1sec. Warten auf Callback von evohome_IF() 
              
              /*
              https://github.com/svrooij/evohome
              evohome wird installiert in /root/node_modules/@svrooij/evohome
              und muß in /opt/iobroker/node_modules/iobroker.javascript/node_modules/evohome verschoben werden
              in ioBroker JS Instance das additional NPM module: evohome eintragen
              
              Berechnet die Heizlastanforderung in °C (Soll-Ist aller Räume) für WTC-EvoHome Interface
              Regelung der Vorlauftemperatur über WTC-COM bzw. WTC-WEM Portal
              
              EVO Home auf Ausfall Prüfung
              
              */
              
              // Eingangsdaten
              var Out_Root="javascript." + instance + ".haus.Heizung."
              
              // Zimmer
              var S_Raum=[];                                     
              S_Raum[0]='Büro'                // Büro   - Raum namen müssen mit EvoHome übereinstimmen
              S_Raum[1]='Küche'               // Küche 
              S_Raum[2]='Bad'                 // Bad
              S_Raum[3]='Wohnzimmer'          // Wohnzimmer 
              S_Raum[4]='OG Zi links'         // OG Zi Links  
              S_Raum[5]='OG Wohnen';          // OG Wohnen
              S_Raum[6]='OG Küche';           // OG Küche
              S_Raum[7]='OG Zi rechts';       // OG Zi Rechts
              
              // Neue Alias Daten Objekte
              var D_Raum=[];
              D_Raum[0]='Buero';                                 // Raumnamen für Script
              D_Raum[1]='Kueche';                                
              D_Raum[2]='Bad';                                   
              D_Raum[3]='Wohnzimmer';                            
              D_Raum[4]='OG_Zi_Links';                                
              D_Raum[5]='OG_Wohnen'; 
              D_Raum[6]='OG_Kueche';                                 
              D_Raum[7]='OG_Zi_Rechts';
              
              // Korrekturwerte für Raum Temperatur  (Faktor für RTdiff < 0)
              var K_Raum=[];
              K_Raum[0]=1                            // 'Buero';                                                            
              K_Raum[1]=1                            // Küche
              K_Raum[2]=1                            //'Bad';                                   
              K_Raum[3]=1                            //'Wohnzimmer';                            
              K_Raum[4]=1                            //'OG_Zi_Links';                                
              K_Raum[5]=1                            //'OG_Wohnen'; 
              K_Raum[6]=1                            //'OG_Kueche';                                 
              K_Raum[7]=1                            //'OG_Zi_Rechts'
                                        
              
              //Konstanten für erforderliche Heizleistung
              const Kwert = 0.4               // kWert 1.1 = Neubau; 2.2 = Gebäude ab 1975; 3 = Altbau 
              var V_Raum=[];                  // Raum Volumen in m³
              V_Raum[0]=26.00*2.53                      // 'Buero'   Fläche * Raumhöhe in qm*m               
              V_Raum[1]=45.77*2.30                      // 'Kueche'                                
              V_Raum[2]=18.75*2.63                      // 'Bad'                                  
              V_Raum[3]=72.68*2.55                      // 'Wohnzimmer'                            
              V_Raum[4]=25.00*2.53                      // 'OG_Zi_Links';                               
              V_Raum[5]=12.00*2.53                      // 'OG_Wohnen' 
              V_Raum[6]=16.00*2.53                      // 'OG_Kueche';                                 
              V_Raum[7]=25.00*2.53                      // 'OG_Zi_Rechts'   Summe Volumen: 603m³ WF UG: 163  OG: 72
              
              var Raum_VTemp=[0,0,0,0,0,0,0,0];
              var Raum_SollTemp=[0,0,0,0,0,0,0,0];
              
              var RTdiff =  0
              var RTdiff_max =  0
              var maxSollTemp = 0
              var TempDiff_Sum = 0;
              var Heizleistung_Soll = 0
              var Heizleistung_Ist = 0
              var MaxTempRaum = "";
              var LastIndex = 0
              
              // Alle Zimmer Tempraturen
              const Temp_Aus  = 13.0     // Urlaub, Heizung aus
              const Temp_FOA  = 13.6     // Fenster offen Alarm
              const Temp_Abw  = 15.0     // abwesend (Smartphone)
              const Temp_Anw  = 21.1     // anwesend (Smartphone)
              const Temp_Abs  = 18.0     // Absenktemp (EvoHome)
              const Temp_Norm = 21.0     // Normaltemp (EvoHome)
              const Temp_Max = 22.5      // Max. Temperatur (Sonneneinstrahlung)
              
              var ArrayTD=[]
              
              // -------------------------  Alias Daten Objekte anlegen -----------------
              
              S_Raum.forEach(function(element, index) {
                  createState(Out_Root+D_Raum[index]+".Soll", {
                          name: D_Raum[index]+"-Soll",
                          type: 'number',
                          unit: '°C',
                  });
              });
              S_Raum.forEach(function(element, index) {
                  createState(Out_Root+D_Raum[index]+".Temperatur", {
                          name: D_Raum[index]+"-Ist",
                          type: 'number',
                          unit: '°C',
                  });
              });
              S_Raum.forEach(function(element, index) {
                  createState(Out_Root+D_Raum[index]+".FensterOffen", {
                          name: "ist Fenster offen",
                          type: 'boolean',
                          unit: '',
                  });
              });
              S_Raum.forEach(function(element, index) {
                  createState(Out_Root+D_Raum[index]+".Abwesend", {
                          name: "ist Smartphone abwesend",
                          type: 'boolean',
                          unit: '',
                  });
              })
              S_Raum.forEach(function(element, index) {
                  createState(Out_Root+D_Raum[index]+".evoDeviceID", {
                          name: "EvoHome Device ID",
                          type: 'number',
                          unit: '',
                  })
              })
              
              /*
              S_Raum.forEach(function(element, index) {
                  createState(Out_Root+D_Raum[index]+".Steigung", {
                          name: D_Raum[index]+"-Steigung",
                          type: 'number',
                          unit: 'K/Std.',
                  });
              });
              */
              
              createState(Out_Root+"Kessel.RTdiff_max_Raum", {
                          name: "RTdiff welcher Raum",
                          type: 'string',
                          unit: '',
              });
              
              createState(Out_Root+"Kessel.RTdiff", {
                          name: "akt. Soll-Ist Raumtemp",
                          type: 'number',
                          unit: 'K',
              });
              
              createState(Out_Root+"Kessel.RTdiff_max", {
                          name: "max. Soll-Ist Raumtemp",
                          type: 'number',
                          unit: 'K',
              });
              
              createState(Out_Root+"Kessel.Heizleistung_Soll", {
                          name: "Summe erforderliche Heizleistung",
                          type: 'number',
                          unit: 'Watt',
              });
              createState(Out_Root+"Stoerung.EHLastTS", {              
                          name: "EvoHome letzte RT Änderung vor",
                          type: 'number',
                          unit: 'Min.',
              })
              createState(Out_Root+"Stoerung.EHLastTS_R", {              
                          name: "bei Raum",
                          type: 'string',
                          unit: 'Min.',
              })
              createState(Out_Root+"Stoerung.EHLastTS_max", {              
                          name: "EvoHome letzte RT Änderung max.",
                          type: 'number',
                          unit: 'Min.',
              })
              createState(Out_Root+"Stoerung.EHLastTS_max_R", {              
                          name: "bei Raum",
                          type: 'string',
                          unit: 'Min.',
              })
              
              // ---- letzte Temperaturänderung feststellen
              function LastTempCh(LastTS, index){
                  let RTobj = getState(Out_Root+D_Raum[index]+'.Temperatur')  
                  if (RTobj.ts < LastTS){
                      LastTS = RTobj.ts
                      let Dauer = Math.round( (Date.now()-LastTS)/1000/60 )   
                      // log('#### '+D_Raum[index]+' EVOHome letzte Temperatur vor min.: '+Dauer  )
                      setState("javascript.0.haus.Heizung.Stoerung.EHLastTS",Dauer )  // letzte Raumtemperatur Änderung vor x Min.
                      setState("javascript.0.haus.Heizung.Stoerung.EHLastTS_R",D_Raum[index])
                      if ( Dauer >= getState('javascript.0.haus.Heizung.Stoerung.EHLastTS_max').val ){
                          setState('javascript.0.haus.Heizung.Stoerung.EHLastTS_max',Dauer)
                          setState('javascript.0.haus.Heizung.Stoerung.EHLastTS_max_R',D_Raum[index])
                      }  
                  }
              } // LastTemp
              
              schedule("1 0 * * *", function () {                                     // "1 0 * * *"  um 0:01 täglich
                  setState('javascript.0.haus.Heizung.Stoerung.EHLastTS_max',0)       // max Werte Vortag löschen
                  setState('javascript.0.haus.Heizung.Stoerung.EHLastTS_max_R','')
              })
              //###############################  Ist und Soll Temperatur abrufen ###########################################
              RaumAbw()                                        // Für Programmstart
              setInterval(RaumAbw,5*60*1000)                  // Intervall wg Fenster offen u. Handy ab
              function RaumAbw(obj) {
                  let Startzeit = getState(Out_Root+D_Raum[0]+".Soll").ts
                    evohome_IF()                             // Ist- und Solltemperaturen abrufen, Absenkung prüfen
                  let Endtzeit = getState(Out_Root+D_Raum[0]+".Soll").ts
                  log('evohome_IF() Funktion Dauer: '+(Endtzeit-Startzeit)+' ms.')
                  
                  RTdiff =  0;
                  TempDiff_Sum = 0;
                  MaxTempRaum = ""
                  RTdiff_max = 0
                  maxSollTemp = 0
                  Heizleistung_Soll = 0
                  var LastTS = Date.now()
                  var SollTemp = 0, IstTemp = 0
                  setTimeout(function () {                            // 1sec. Warten auf Callback von evohome_IF() 
                      S_Raum.forEach(function(element, index) {       // Schleife für jeden Raum 
                          LastTempCh(LastTS, index)                   // letzte Temperaturänderung feststellen
                     
                          SollTemp = getState(Out_Root+D_Raum[index]+".Soll").val
                          IstTemp  =  getState(Out_Root+D_Raum[index]+".Temperatur").val 
              
                          // Berechnung der maximalen negativen Temperaturdifferenz (Ist-Soll) aller Räume
                          if (IstTemp > Temp_Max) IstTemp = Temp_Max + 0.1   // wg. Sonneneinstrahlung
                          RTdiff = (IstTemp-SollTemp) 
                          
                          if (RTdiff < 0) RTdiff = RTdiff * K_Raum[index]
              
                          // Temperatur für benötigte Heizleistung = RTsoll - AT
                          let Tempdiff = SollTemp - getState('mqtt.0.haus.keller.HumiFan.Sensor.Aussen.Temperatur').val
                          var Heizleistung = Math.round((V_Raum[index] * Kwert * Tempdiff * 1.16) )          // 1.16 = kcal in Watt 
                          if (Heizleistung > 0 ) Heizleistung_Soll += Heizleistung                    // summe Heizleistung in Watt
                          Heizleistung_Ist = getState('mqtt.0.haus.keller.WMZ.WMleistung').val
              
                          // log(D_Raum[index]+' RTdiff: '+RTdiff+' RTdiff_max: '+ RTdiff_max);
              
                          TempDiff_Sum += RTdiff;
                          if ( RTdiff < RTdiff_max ) {       // der "kälteste Raum" wird gesucht
                              RTdiff_max = RTdiff;           // -1 = Raum zu kalt, aufheizen
                              MaxTempRaum = D_Raum[index];
                          }
                          if (SollTemp > maxSollTemp)  maxSollTemp = SollTemp          // aktuell max. Solltemperatur
              
                          if (MaxTempRaum == 'Kueche') MaxTempRaum = 'Küche'
                          if (MaxTempRaum == 'Buero') MaxTempRaum = 'Büro'
                          LastIndex = index+1
                      });  // Schleife für jeden Raum ######################################
              
                      // TempSteigung(element, index)             // Berechnet die Temperatur-Steigung des Raumes
              
                      // Durchschnitt Energiebedarf - Wennn ein Raum zu kalt (<-1.1), dann bestimmt er die Temperatur
                      RTdiff = RTdiff_max/4     
                      if (RTdiff_max >= -0.9) RTdiff =  round(TempDiff_Sum/LastIndex,1)       // 19.1.2021  0.6; 4.2.2021 1.1
              
                      // RTdiff =  AAverage(ArrayTD,RTdiff,5)
                      
                      // log('RTdiff: '+ArrayTD+'  Median: '+AMedian(ArrayTD)+' Average: '+AAverage(ArrayTD))
                      // log('--- '+MaxTempRaum+' '+RTdiff_max+' RTDiff: '+RTdiff)
              
                      setState(Out_Root+"Kessel.RTdiff",round(RTdiff,3))                    // Temp.Differenz für Regelung
                      setState(Out_Root+"Kessel.RTdiff_max",round(RTdiff_max,3))              // max. Temp Differenz 
                      setState(Out_Root+"Kessel.RTdiff_max_Raum",MaxTempRaum);     // bei Raum im Klartext 
                      setState(Out_Root+"Kessel.Heizleistung_Soll",round(Heizleistung_Soll*1.1,0))    // +10% für übrige Räume
                  },1000)
              }  // function RaumAbw
              //###############################  Ist und Soll Temperatur abrufen ###########################################
              
              
              
              // Berechnet die Steigung der Raumtemperatur der letzten 30min. in K/Std.
              // Normalwerte: Aufheizen: ca. 3K/h ; abkühlen ca. 1K/h
              function TempSteigung(element, index){
                  var IstTemp = parseFloat(  getState(Out_Root+D_Raum[index]+".Temperatur").val)
                  
                  //  ++++++++++++++++  evtl. nur bei Änderung Steigung berechnen, dann aber jede Min. aufrufen
                  // if (Raum_VTemp[index] != IstTemp) {         // Raumtemperatur geändert
                      Raum_VTemp[index] = IstTemp
                      // var vonDatum = new Date("2020-02-06 6:00:00").getTime()  // in UnixTime ms.
                      // var bisDatum = new Date("2020-02-06 8:00:00").getTime()
              
                     var bisDatum = Date.now()
                     var vonDatum = bisDatum - 3600*1000;       // vor 1 Std.
              
                     mysqlData_Steigung(vonDatum, bisDatum, Out_Root+D_Raum[index]+".Temperatur", index)  // return steigung nicht möglich, weil asynchron
                  // }
              
              
              }  // function TempSteigung
              
              function mysqlData_Steigung(vonDatum, bisDatum, DatObj, index){
              
              var vTemp, vDatum, bTemp, bDatum
              var myQuery="SELECT val AS wert, ts as datum  \
                                      FROM iobroker.ts_number \
                                      WHERE id=(SELECT id FROM iobroker.datapoints WHERE NAME='"+DatObj+"') \
                                      AND  ts <= '"+vonDatum+"'  \
                                      ORDER BY ts DESC LIMIT 1"
                                                      // ts < Datum weil das die Temperatur zur Zeit vonDatum ist
               
                      // log("--->>>>"+myQuery);
                  sendTo('sql.0', 'query', myQuery, function (result) {
                      if (result.error) {
                          logerror("Heizung_Alias SQL querry Fehler 1:  "+result.error);
                      } else {
                          vTemp=result.result[0].wert;
                          vDatum = result.result[0].datum;      // var date = new Date(unix_timestamp * 1000);
              
                          var myQuery="SELECT val AS wert, ts as datum  \
                                          FROM iobroker.ts_number \
                                          WHERE id=(SELECT id FROM iobroker.datapoints WHERE NAME='"+DatObj+"') \
                                          AND  ts <= '"+bisDatum+"'  \
                                          ORDER BY ts DESC LIMIT 1"
                              sendTo('sql.0', 'query', myQuery, function (result) {
                                  if (result.error) {
                                      logerror("Heizung_Alias SQL querry Fehler 2:  "+result.error);
                                  } else {
                                      bTemp=result.result[0].wert;
                                      bDatum = result.result[0].datum;      // var date = new Date(unix_timestamp * 1000);
              
                                      var Temperatur = (bTemp-vTemp)
                                      var Datum = (bDatum-vDatum)/1000      // in sec.
                                      var steigung = 0
                                      if (Datum != 0) steigung = Math.round(Temperatur/Datum*36000) /10;   // in K/Std.
                                      // log(D_Raum[index]+ "  Steigung: "+steigung)
                                      setState(Out_Root+D_Raum[index]+".Steigung",steigung); 
                                  }
                              });
                      }
                  });
              }  // function mysqlData_Steigung
              
              
              //############################ alle Raumemperaturen von EvoHome auslesen   ############################
              function evohome_IF(){
                  const EvohomeClient = require('evohome').EvohomeClient
                  const HeatSetpointStatus = require('evohome').HeatSetpointStatus
                  const username = 'xxxxxxxxx'
                  const password = 'yyyyyyy'
                  const evohomeClient = new EvohomeClient(username, password)
              
                  evohomeClient.getLocationsWithAutoLogin(300).then(locations => {      // (x) = Session Abbruch nach x Sekunden
                  // log('JSON OBJ: '+JSON.stringify(locations))
               
                  S_Raum.forEach(function(element, index){            // z.Zt. 8 Räume 0-7
                      const deviceId = locations[0].devices[index].deviceID   
                      var Raum_name = locations[0].devices[index].name
                      var Rindex = S_Raum.indexOf(Raum_name)               // suchen Raumname in S_Raum Array
                      if (Rindex != -1) {
                          var IstTemp = locations[0].devices[index].thermostat.indoorTemperature
                          var SollTemp = locations[0].devices[index].thermostat.changeableValues.heatSetpoint.value   
                          // log(Rindex+'-Zimmer: '+Raum_name+'  Temperatur: '+IstTemp+'  Soll Temp: '+SollTemp)
                          
                          SollTemp = Absenkung(deviceId,Rindex,SollTemp,evohomeClient,HeatSetpointStatus)
              
                          setStateAsync(Out_Root+D_Raum[Rindex]+".Temperatur",IstTemp)
                          setStateAsync(Out_Root+D_Raum[Rindex]+".Soll",SollTemp)    
                          setStateAsync(Out_Root+D_Raum[Rindex]+".evoDeviceID",deviceId)
              
                          // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Hold, 15)           // Wohnzimmer Temp. setzen
                          // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Temporary, 15,10)   // Wohnzimmer auf 15° 30 min. lang
                          // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Scheduled)     // Wohnzimmer auf Zeitplan zurücksetzen
                      } else {
                          logerror('Raum '+Raum_name+' nicht gefunden')
                      }
                  }) // forEach
                  }).catch(err => {
                      log('Fehler bei EvoHome Abfrage: '+ err)
                      // process.exit(3)
                  })
              } // evohome_IF
              
              //############################   Absenkung bei Fenster offen oder Handy ab     ########################################
              function Absenkung(deviceId,Rindex,SollTemp,evohomeClient,HeatSetpointStatus){
                  if ( getState(Out_Root+D_Raum[Rindex]+'.FensterOffen').val ){                    // Fenster offen
                      // log('Fenster offen: '+D_Raum[Rindex])
                      if (SollTemp != Temp_FOA) {
                          evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Hold,Temp_FOA)     // Temp. setzen
                          SollTemp = Temp_FOA
                      }
                  } else {                                                                        // Fenster zu
                      // log('Fenster zu: '+D_Raum[Rindex])
                      if (SollTemp == Temp_FOA){
                          // log('Fenster zu: '+D_Raum[Rindex])
                          evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Scheduled)                                                    // Zeitplan Temperatur
                      } 
              
                      if ( getState(Out_Root+D_Raum[Rindex]+'.Abwesend').val ){                     // Handy ab
                          if (getState('javascript.0.haus.Heizung.Stoerung.Abs_Abwesend').val) {   // Absenkung ausgeschaltet?
                              // log('Handy ab: '+D_Raum[Rindex]+' SollTemp: '+SollTemp)
                              if (SollTemp != Temp_Abw) {
                                  evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Hold,Temp_Abw)
                                  SollTemp = Temp_Abw
                              }
                          }
                      } else { 
                          if (SollTemp == Temp_Abw) {
                              // log('Handy an-: '+D_Raum[Rindex]+' SollTemp: '+SollTemp)             // Handy an
                              evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Scheduled)                                                    // Zeitplan Temperatur
                          }
                      }
                  }
              return SollTemp
              }  // Absenkung
              
              
              AlCalzoneA 1 Antwort Letzte Antwort
              0
              • hanssH hanss

                @alcalzone

                Bitte, wenn Du dir das antun möchtest - ist recht umfangreich.

                Inzwischen denke ich, dass es besser wäre, statt mit dem festen Timeout
                setTimeout(function () {
                darauf zu warten, bis die funktion evohome_IF() komplett fertig ist.
                Der komplette Code ist weiter unten.
                Danke.

                function RaumAbw(obj) {
                    let Startzeit = getState(Out_Root+D_Raum[0]+".Soll").ts
                      evohome_IF()                             // Ist- und Solltemperaturen abrufen, Absenkung prüfen
                    let Endtzeit = getState(Out_Root+D_Raum[0]+".Soll").ts
                    log('evohome_IF() Funktion Dauer: '+(Endtzeit-Startzeit)+' ms.')
                    
                    RTdiff =  0;
                    TempDiff_Sum = 0;
                    MaxTempRaum = ""
                    RTdiff_max = 0
                    maxSollTemp = 0
                    Heizleistung_Soll = 0
                    var LastTS = Date.now()
                    var SollTemp = 0, IstTemp = 0
                    setTimeout(function () {                            // 1sec. Warten auf Callback von evohome_IF() 
                
                /*
                https://github.com/svrooij/evohome
                evohome wird installiert in /root/node_modules/@svrooij/evohome
                und muß in /opt/iobroker/node_modules/iobroker.javascript/node_modules/evohome verschoben werden
                in ioBroker JS Instance das additional NPM module: evohome eintragen
                
                Berechnet die Heizlastanforderung in °C (Soll-Ist aller Räume) für WTC-EvoHome Interface
                Regelung der Vorlauftemperatur über WTC-COM bzw. WTC-WEM Portal
                
                EVO Home auf Ausfall Prüfung
                
                */
                
                // Eingangsdaten
                var Out_Root="javascript." + instance + ".haus.Heizung."
                
                // Zimmer
                var S_Raum=[];                                     
                S_Raum[0]='Büro'                // Büro   - Raum namen müssen mit EvoHome übereinstimmen
                S_Raum[1]='Küche'               // Küche 
                S_Raum[2]='Bad'                 // Bad
                S_Raum[3]='Wohnzimmer'          // Wohnzimmer 
                S_Raum[4]='OG Zi links'         // OG Zi Links  
                S_Raum[5]='OG Wohnen';          // OG Wohnen
                S_Raum[6]='OG Küche';           // OG Küche
                S_Raum[7]='OG Zi rechts';       // OG Zi Rechts
                
                // Neue Alias Daten Objekte
                var D_Raum=[];
                D_Raum[0]='Buero';                                 // Raumnamen für Script
                D_Raum[1]='Kueche';                                
                D_Raum[2]='Bad';                                   
                D_Raum[3]='Wohnzimmer';                            
                D_Raum[4]='OG_Zi_Links';                                
                D_Raum[5]='OG_Wohnen'; 
                D_Raum[6]='OG_Kueche';                                 
                D_Raum[7]='OG_Zi_Rechts';
                
                // Korrekturwerte für Raum Temperatur  (Faktor für RTdiff < 0)
                var K_Raum=[];
                K_Raum[0]=1                            // 'Buero';                                                            
                K_Raum[1]=1                            // Küche
                K_Raum[2]=1                            //'Bad';                                   
                K_Raum[3]=1                            //'Wohnzimmer';                            
                K_Raum[4]=1                            //'OG_Zi_Links';                                
                K_Raum[5]=1                            //'OG_Wohnen'; 
                K_Raum[6]=1                            //'OG_Kueche';                                 
                K_Raum[7]=1                            //'OG_Zi_Rechts'
                                          
                
                //Konstanten für erforderliche Heizleistung
                const Kwert = 0.4               // kWert 1.1 = Neubau; 2.2 = Gebäude ab 1975; 3 = Altbau 
                var V_Raum=[];                  // Raum Volumen in m³
                V_Raum[0]=26.00*2.53                      // 'Buero'   Fläche * Raumhöhe in qm*m               
                V_Raum[1]=45.77*2.30                      // 'Kueche'                                
                V_Raum[2]=18.75*2.63                      // 'Bad'                                  
                V_Raum[3]=72.68*2.55                      // 'Wohnzimmer'                            
                V_Raum[4]=25.00*2.53                      // 'OG_Zi_Links';                               
                V_Raum[5]=12.00*2.53                      // 'OG_Wohnen' 
                V_Raum[6]=16.00*2.53                      // 'OG_Kueche';                                 
                V_Raum[7]=25.00*2.53                      // 'OG_Zi_Rechts'   Summe Volumen: 603m³ WF UG: 163  OG: 72
                
                var Raum_VTemp=[0,0,0,0,0,0,0,0];
                var Raum_SollTemp=[0,0,0,0,0,0,0,0];
                
                var RTdiff =  0
                var RTdiff_max =  0
                var maxSollTemp = 0
                var TempDiff_Sum = 0;
                var Heizleistung_Soll = 0
                var Heizleistung_Ist = 0
                var MaxTempRaum = "";
                var LastIndex = 0
                
                // Alle Zimmer Tempraturen
                const Temp_Aus  = 13.0     // Urlaub, Heizung aus
                const Temp_FOA  = 13.6     // Fenster offen Alarm
                const Temp_Abw  = 15.0     // abwesend (Smartphone)
                const Temp_Anw  = 21.1     // anwesend (Smartphone)
                const Temp_Abs  = 18.0     // Absenktemp (EvoHome)
                const Temp_Norm = 21.0     // Normaltemp (EvoHome)
                const Temp_Max = 22.5      // Max. Temperatur (Sonneneinstrahlung)
                
                var ArrayTD=[]
                
                // -------------------------  Alias Daten Objekte anlegen -----------------
                
                S_Raum.forEach(function(element, index) {
                    createState(Out_Root+D_Raum[index]+".Soll", {
                            name: D_Raum[index]+"-Soll",
                            type: 'number',
                            unit: '°C',
                    });
                });
                S_Raum.forEach(function(element, index) {
                    createState(Out_Root+D_Raum[index]+".Temperatur", {
                            name: D_Raum[index]+"-Ist",
                            type: 'number',
                            unit: '°C',
                    });
                });
                S_Raum.forEach(function(element, index) {
                    createState(Out_Root+D_Raum[index]+".FensterOffen", {
                            name: "ist Fenster offen",
                            type: 'boolean',
                            unit: '',
                    });
                });
                S_Raum.forEach(function(element, index) {
                    createState(Out_Root+D_Raum[index]+".Abwesend", {
                            name: "ist Smartphone abwesend",
                            type: 'boolean',
                            unit: '',
                    });
                })
                S_Raum.forEach(function(element, index) {
                    createState(Out_Root+D_Raum[index]+".evoDeviceID", {
                            name: "EvoHome Device ID",
                            type: 'number',
                            unit: '',
                    })
                })
                
                /*
                S_Raum.forEach(function(element, index) {
                    createState(Out_Root+D_Raum[index]+".Steigung", {
                            name: D_Raum[index]+"-Steigung",
                            type: 'number',
                            unit: 'K/Std.',
                    });
                });
                */
                
                createState(Out_Root+"Kessel.RTdiff_max_Raum", {
                            name: "RTdiff welcher Raum",
                            type: 'string',
                            unit: '',
                });
                
                createState(Out_Root+"Kessel.RTdiff", {
                            name: "akt. Soll-Ist Raumtemp",
                            type: 'number',
                            unit: 'K',
                });
                
                createState(Out_Root+"Kessel.RTdiff_max", {
                            name: "max. Soll-Ist Raumtemp",
                            type: 'number',
                            unit: 'K',
                });
                
                createState(Out_Root+"Kessel.Heizleistung_Soll", {
                            name: "Summe erforderliche Heizleistung",
                            type: 'number',
                            unit: 'Watt',
                });
                createState(Out_Root+"Stoerung.EHLastTS", {              
                            name: "EvoHome letzte RT Änderung vor",
                            type: 'number',
                            unit: 'Min.',
                })
                createState(Out_Root+"Stoerung.EHLastTS_R", {              
                            name: "bei Raum",
                            type: 'string',
                            unit: 'Min.',
                })
                createState(Out_Root+"Stoerung.EHLastTS_max", {              
                            name: "EvoHome letzte RT Änderung max.",
                            type: 'number',
                            unit: 'Min.',
                })
                createState(Out_Root+"Stoerung.EHLastTS_max_R", {              
                            name: "bei Raum",
                            type: 'string',
                            unit: 'Min.',
                })
                
                // ---- letzte Temperaturänderung feststellen
                function LastTempCh(LastTS, index){
                    let RTobj = getState(Out_Root+D_Raum[index]+'.Temperatur')  
                    if (RTobj.ts < LastTS){
                        LastTS = RTobj.ts
                        let Dauer = Math.round( (Date.now()-LastTS)/1000/60 )   
                        // log('#### '+D_Raum[index]+' EVOHome letzte Temperatur vor min.: '+Dauer  )
                        setState("javascript.0.haus.Heizung.Stoerung.EHLastTS",Dauer )  // letzte Raumtemperatur Änderung vor x Min.
                        setState("javascript.0.haus.Heizung.Stoerung.EHLastTS_R",D_Raum[index])
                        if ( Dauer >= getState('javascript.0.haus.Heizung.Stoerung.EHLastTS_max').val ){
                            setState('javascript.0.haus.Heizung.Stoerung.EHLastTS_max',Dauer)
                            setState('javascript.0.haus.Heizung.Stoerung.EHLastTS_max_R',D_Raum[index])
                        }  
                    }
                } // LastTemp
                
                schedule("1 0 * * *", function () {                                     // "1 0 * * *"  um 0:01 täglich
                    setState('javascript.0.haus.Heizung.Stoerung.EHLastTS_max',0)       // max Werte Vortag löschen
                    setState('javascript.0.haus.Heizung.Stoerung.EHLastTS_max_R','')
                })
                //###############################  Ist und Soll Temperatur abrufen ###########################################
                RaumAbw()                                        // Für Programmstart
                setInterval(RaumAbw,5*60*1000)                  // Intervall wg Fenster offen u. Handy ab
                function RaumAbw(obj) {
                    let Startzeit = getState(Out_Root+D_Raum[0]+".Soll").ts
                      evohome_IF()                             // Ist- und Solltemperaturen abrufen, Absenkung prüfen
                    let Endtzeit = getState(Out_Root+D_Raum[0]+".Soll").ts
                    log('evohome_IF() Funktion Dauer: '+(Endtzeit-Startzeit)+' ms.')
                    
                    RTdiff =  0;
                    TempDiff_Sum = 0;
                    MaxTempRaum = ""
                    RTdiff_max = 0
                    maxSollTemp = 0
                    Heizleistung_Soll = 0
                    var LastTS = Date.now()
                    var SollTemp = 0, IstTemp = 0
                    setTimeout(function () {                            // 1sec. Warten auf Callback von evohome_IF() 
                        S_Raum.forEach(function(element, index) {       // Schleife für jeden Raum 
                            LastTempCh(LastTS, index)                   // letzte Temperaturänderung feststellen
                       
                            SollTemp = getState(Out_Root+D_Raum[index]+".Soll").val
                            IstTemp  =  getState(Out_Root+D_Raum[index]+".Temperatur").val 
                
                            // Berechnung der maximalen negativen Temperaturdifferenz (Ist-Soll) aller Räume
                            if (IstTemp > Temp_Max) IstTemp = Temp_Max + 0.1   // wg. Sonneneinstrahlung
                            RTdiff = (IstTemp-SollTemp) 
                            
                            if (RTdiff < 0) RTdiff = RTdiff * K_Raum[index]
                
                            // Temperatur für benötigte Heizleistung = RTsoll - AT
                            let Tempdiff = SollTemp - getState('mqtt.0.haus.keller.HumiFan.Sensor.Aussen.Temperatur').val
                            var Heizleistung = Math.round((V_Raum[index] * Kwert * Tempdiff * 1.16) )          // 1.16 = kcal in Watt 
                            if (Heizleistung > 0 ) Heizleistung_Soll += Heizleistung                    // summe Heizleistung in Watt
                            Heizleistung_Ist = getState('mqtt.0.haus.keller.WMZ.WMleistung').val
                
                            // log(D_Raum[index]+' RTdiff: '+RTdiff+' RTdiff_max: '+ RTdiff_max);
                
                            TempDiff_Sum += RTdiff;
                            if ( RTdiff < RTdiff_max ) {       // der "kälteste Raum" wird gesucht
                                RTdiff_max = RTdiff;           // -1 = Raum zu kalt, aufheizen
                                MaxTempRaum = D_Raum[index];
                            }
                            if (SollTemp > maxSollTemp)  maxSollTemp = SollTemp          // aktuell max. Solltemperatur
                
                            if (MaxTempRaum == 'Kueche') MaxTempRaum = 'Küche'
                            if (MaxTempRaum == 'Buero') MaxTempRaum = 'Büro'
                            LastIndex = index+1
                        });  // Schleife für jeden Raum ######################################
                
                        // TempSteigung(element, index)             // Berechnet die Temperatur-Steigung des Raumes
                
                        // Durchschnitt Energiebedarf - Wennn ein Raum zu kalt (<-1.1), dann bestimmt er die Temperatur
                        RTdiff = RTdiff_max/4     
                        if (RTdiff_max >= -0.9) RTdiff =  round(TempDiff_Sum/LastIndex,1)       // 19.1.2021  0.6; 4.2.2021 1.1
                
                        // RTdiff =  AAverage(ArrayTD,RTdiff,5)
                        
                        // log('RTdiff: '+ArrayTD+'  Median: '+AMedian(ArrayTD)+' Average: '+AAverage(ArrayTD))
                        // log('--- '+MaxTempRaum+' '+RTdiff_max+' RTDiff: '+RTdiff)
                
                        setState(Out_Root+"Kessel.RTdiff",round(RTdiff,3))                    // Temp.Differenz für Regelung
                        setState(Out_Root+"Kessel.RTdiff_max",round(RTdiff_max,3))              // max. Temp Differenz 
                        setState(Out_Root+"Kessel.RTdiff_max_Raum",MaxTempRaum);     // bei Raum im Klartext 
                        setState(Out_Root+"Kessel.Heizleistung_Soll",round(Heizleistung_Soll*1.1,0))    // +10% für übrige Räume
                    },1000)
                }  // function RaumAbw
                //###############################  Ist und Soll Temperatur abrufen ###########################################
                
                
                
                // Berechnet die Steigung der Raumtemperatur der letzten 30min. in K/Std.
                // Normalwerte: Aufheizen: ca. 3K/h ; abkühlen ca. 1K/h
                function TempSteigung(element, index){
                    var IstTemp = parseFloat(  getState(Out_Root+D_Raum[index]+".Temperatur").val)
                    
                    //  ++++++++++++++++  evtl. nur bei Änderung Steigung berechnen, dann aber jede Min. aufrufen
                    // if (Raum_VTemp[index] != IstTemp) {         // Raumtemperatur geändert
                        Raum_VTemp[index] = IstTemp
                        // var vonDatum = new Date("2020-02-06 6:00:00").getTime()  // in UnixTime ms.
                        // var bisDatum = new Date("2020-02-06 8:00:00").getTime()
                
                       var bisDatum = Date.now()
                       var vonDatum = bisDatum - 3600*1000;       // vor 1 Std.
                
                       mysqlData_Steigung(vonDatum, bisDatum, Out_Root+D_Raum[index]+".Temperatur", index)  // return steigung nicht möglich, weil asynchron
                    // }
                
                
                }  // function TempSteigung
                
                function mysqlData_Steigung(vonDatum, bisDatum, DatObj, index){
                
                var vTemp, vDatum, bTemp, bDatum
                var myQuery="SELECT val AS wert, ts as datum  \
                                        FROM iobroker.ts_number \
                                        WHERE id=(SELECT id FROM iobroker.datapoints WHERE NAME='"+DatObj+"') \
                                        AND  ts <= '"+vonDatum+"'  \
                                        ORDER BY ts DESC LIMIT 1"
                                                        // ts < Datum weil das die Temperatur zur Zeit vonDatum ist
                 
                        // log("--->>>>"+myQuery);
                    sendTo('sql.0', 'query', myQuery, function (result) {
                        if (result.error) {
                            logerror("Heizung_Alias SQL querry Fehler 1:  "+result.error);
                        } else {
                            vTemp=result.result[0].wert;
                            vDatum = result.result[0].datum;      // var date = new Date(unix_timestamp * 1000);
                
                            var myQuery="SELECT val AS wert, ts as datum  \
                                            FROM iobroker.ts_number \
                                            WHERE id=(SELECT id FROM iobroker.datapoints WHERE NAME='"+DatObj+"') \
                                            AND  ts <= '"+bisDatum+"'  \
                                            ORDER BY ts DESC LIMIT 1"
                                sendTo('sql.0', 'query', myQuery, function (result) {
                                    if (result.error) {
                                        logerror("Heizung_Alias SQL querry Fehler 2:  "+result.error);
                                    } else {
                                        bTemp=result.result[0].wert;
                                        bDatum = result.result[0].datum;      // var date = new Date(unix_timestamp * 1000);
                
                                        var Temperatur = (bTemp-vTemp)
                                        var Datum = (bDatum-vDatum)/1000      // in sec.
                                        var steigung = 0
                                        if (Datum != 0) steigung = Math.round(Temperatur/Datum*36000) /10;   // in K/Std.
                                        // log(D_Raum[index]+ "  Steigung: "+steigung)
                                        setState(Out_Root+D_Raum[index]+".Steigung",steigung); 
                                    }
                                });
                        }
                    });
                }  // function mysqlData_Steigung
                
                
                //############################ alle Raumemperaturen von EvoHome auslesen   ############################
                function evohome_IF(){
                    const EvohomeClient = require('evohome').EvohomeClient
                    const HeatSetpointStatus = require('evohome').HeatSetpointStatus
                    const username = 'xxxxxxxxx'
                    const password = 'yyyyyyy'
                    const evohomeClient = new EvohomeClient(username, password)
                
                    evohomeClient.getLocationsWithAutoLogin(300).then(locations => {      // (x) = Session Abbruch nach x Sekunden
                    // log('JSON OBJ: '+JSON.stringify(locations))
                 
                    S_Raum.forEach(function(element, index){            // z.Zt. 8 Räume 0-7
                        const deviceId = locations[0].devices[index].deviceID   
                        var Raum_name = locations[0].devices[index].name
                        var Rindex = S_Raum.indexOf(Raum_name)               // suchen Raumname in S_Raum Array
                        if (Rindex != -1) {
                            var IstTemp = locations[0].devices[index].thermostat.indoorTemperature
                            var SollTemp = locations[0].devices[index].thermostat.changeableValues.heatSetpoint.value   
                            // log(Rindex+'-Zimmer: '+Raum_name+'  Temperatur: '+IstTemp+'  Soll Temp: '+SollTemp)
                            
                            SollTemp = Absenkung(deviceId,Rindex,SollTemp,evohomeClient,HeatSetpointStatus)
                
                            setStateAsync(Out_Root+D_Raum[Rindex]+".Temperatur",IstTemp)
                            setStateAsync(Out_Root+D_Raum[Rindex]+".Soll",SollTemp)    
                            setStateAsync(Out_Root+D_Raum[Rindex]+".evoDeviceID",deviceId)
                
                            // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Hold, 15)           // Wohnzimmer Temp. setzen
                            // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Temporary, 15,10)   // Wohnzimmer auf 15° 30 min. lang
                            // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Scheduled)     // Wohnzimmer auf Zeitplan zurücksetzen
                        } else {
                            logerror('Raum '+Raum_name+' nicht gefunden')
                        }
                    }) // forEach
                    }).catch(err => {
                        log('Fehler bei EvoHome Abfrage: '+ err)
                        // process.exit(3)
                    })
                } // evohome_IF
                
                //############################   Absenkung bei Fenster offen oder Handy ab     ########################################
                function Absenkung(deviceId,Rindex,SollTemp,evohomeClient,HeatSetpointStatus){
                    if ( getState(Out_Root+D_Raum[Rindex]+'.FensterOffen').val ){                    // Fenster offen
                        // log('Fenster offen: '+D_Raum[Rindex])
                        if (SollTemp != Temp_FOA) {
                            evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Hold,Temp_FOA)     // Temp. setzen
                            SollTemp = Temp_FOA
                        }
                    } else {                                                                        // Fenster zu
                        // log('Fenster zu: '+D_Raum[Rindex])
                        if (SollTemp == Temp_FOA){
                            // log('Fenster zu: '+D_Raum[Rindex])
                            evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Scheduled)                                                    // Zeitplan Temperatur
                        } 
                
                        if ( getState(Out_Root+D_Raum[Rindex]+'.Abwesend').val ){                     // Handy ab
                            if (getState('javascript.0.haus.Heizung.Stoerung.Abs_Abwesend').val) {   // Absenkung ausgeschaltet?
                                // log('Handy ab: '+D_Raum[Rindex]+' SollTemp: '+SollTemp)
                                if (SollTemp != Temp_Abw) {
                                    evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Hold,Temp_Abw)
                                    SollTemp = Temp_Abw
                                }
                            }
                        } else { 
                            if (SollTemp == Temp_Abw) {
                                // log('Handy an-: '+D_Raum[Rindex]+' SollTemp: '+SollTemp)             // Handy an
                                evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Scheduled)                                                    // Zeitplan Temperatur
                            }
                        }
                    }
                return SollTemp
                }  // Absenkung
                
                
                AlCalzoneA Offline
                AlCalzoneA Offline
                AlCalzone
                Developer
                schrieb am zuletzt editiert von AlCalzone
                #10

                @hanss sagte in setState's in Funktionen:

                Die oben besprochenen Änderungen hast du jetzt noch nicht drin... bzw. nicht vollständig - da kann es auch nicht gehen...

                Hier die Änderungen im Einzelnen:
                ed0fa460-d418-485f-9c0c-5a12ba749589-grafik.png
                ^ Fehlerabfrage heraus gezogen, damit abgebrochen werden kann.

                [Grafik entfernt]
                ^ Unnötiges Timeout entfernt, da jetzt gewartet wird

                [Grafik entfernt]
                ^ Die zuvor besprochenen Änderungen komplett eingefügt.

                Anbei das vollständige Skript:
                evohome-neu.js

                Hoffe ich hab nichts vergessen...

                Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

                hanssH 1 Antwort Letzte Antwort
                0
                • AlCalzoneA AlCalzone

                  @hanss sagte in setState's in Funktionen:

                  Die oben besprochenen Änderungen hast du jetzt noch nicht drin... bzw. nicht vollständig - da kann es auch nicht gehen...

                  Hier die Änderungen im Einzelnen:
                  ed0fa460-d418-485f-9c0c-5a12ba749589-grafik.png
                  ^ Fehlerabfrage heraus gezogen, damit abgebrochen werden kann.

                  [Grafik entfernt]
                  ^ Unnötiges Timeout entfernt, da jetzt gewartet wird

                  [Grafik entfernt]
                  ^ Die zuvor besprochenen Änderungen komplett eingefügt.

                  Anbei das vollständige Skript:
                  evohome-neu.js

                  Hoffe ich hab nichts vergessen...

                  hanssH Offline
                  hanssH Offline
                  hanss
                  schrieb am zuletzt editiert von hanss
                  #11

                  @alcalzone

                  SUPER! Super Service mit dem vollständigen Script.
                  Hat auf Anhieb funktioniert.
                  Das hätte ich nie hinbekommen, da braucht es noch einige Zeit, obwohl ich
                  Deine Erläuterungen zweimal gelesen habe.

                  Vielen, vielen Dank.

                  Noch eine Frage:
                  Wartet jetzt nur die komplette Funktion async function RaumAbw(obj) {
                  bis await evohome_IF() zurück ist?
                  Ich gehe davon aus, das alles Andere weiterläuft?

                  AlCalzoneA 1 Antwort Letzte Antwort
                  0
                  • hanssH hanss

                    @alcalzone

                    SUPER! Super Service mit dem vollständigen Script.
                    Hat auf Anhieb funktioniert.
                    Das hätte ich nie hinbekommen, da braucht es noch einige Zeit, obwohl ich
                    Deine Erläuterungen zweimal gelesen habe.

                    Vielen, vielen Dank.

                    Noch eine Frage:
                    Wartet jetzt nur die komplette Funktion async function RaumAbw(obj) {
                    bis await evohome_IF() zurück ist?
                    Ich gehe davon aus, das alles Andere weiterläuft?

                    AlCalzoneA Offline
                    AlCalzoneA Offline
                    AlCalzone
                    Developer
                    schrieb am zuletzt editiert von
                    #12

                    @hanss Korrekt. Außer du setzt await vor die Aufrufe von RaumAbw.

                    Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

                    1 Antwort Letzte Antwort
                    0
                    • AlCalzoneA AlCalzone

                      @hanss Die enthaltende Funktion muss als async deklariert sein. Das beißt sich aber auch meit deinem .forEach, welches du am besten gegen eine for-Schleife ersetzt. Ich hab hier nur die minimal nötige Änderung gemacht - so richtig erschließt sich mir dein Umgang mit dem Array nicht (Iteration durch eins, Zugriff auf ein anderes) 😅:

                      
                      async function evohome_IF(){
                          const EvohomeClient = require('evohome').EvohomeClient
                          const HeatSetpointStatus = require('evohome').HeatSetpointStatus
                          const username = 'USERNAME'
                          const password = 'PASSWORT'
                          const evohomeClient = new EvohomeClient(username, password)
                       
                          evohomeClient.getLocationsWithAutoLogin(300).then(locations => {      // (x) = Session Abbruch nach x Sekunden
                          // log('JSON OBJ: '+JSON.stringify(locations))
                       
                         // Durch Array iterieren, im Kontext der aktuellen Funktion
                         for (let index = 0; index < S_Raum.length; index++) {            // z.Zt. 8 Räume 0-7
                              const deviceId = locations[0].devices[index].deviceID   
                              var Raum_name = locations[0].devices[index].name
                              var Rindex = S_Raum.indexOf(Raum_name)               // suchen Raumname in S_Raum Array
                              if (Rindex != -1) {
                                  var IstTemp = locations[0].devices[index].thermostat.indoorTemperature
                                  var SollTemp = locations[0].devices[index].thermostat.changeableValues.heatSetpoint.value   
                                  // log(Rindex+'-Zimmer: '+Raum_name+'  Temperatur: '+IstTemp+'  Soll Temp: '+SollTemp)
                                  
                                  SollTemp = Absenkung(deviceId,Rindex,SollTemp,evohomeClient,HeatSetpointStatus)
                       
                                  await setStateAsync(Out_Root+D_Raum[Rindex]+".Temperatur",IstTemp)
                                  await setStateAsync(Out_Root+D_Raum[Rindex]+".Soll",SollTemp)    
                                  await setStateAsync(Out_Root+D_Raum[Rindex]+".evoDeviceID",deviceId)
                       
                                  // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Hold, 15)           // Wohnzimmer Temp. setzen
                                  // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Temporary, 15,10)   // Wohnzimmer auf 15° 30 min. lang
                                  // if (x==7) evohomeClient.setHeatSetpoint(deviceId, HeatSetpointStatus.Scheduled)     // Wohnzimmer auf Zeitplan zurücksetzen
                              } else {
                                  logerror('Raum '+Raum_name+' nicht gefunden')
                              }
                          } // for
                          }).catch(err => {
                              log('Fehler bei EvoHome Abfrage: '+ err)
                              // process.exit(3)
                          })
                      } // evohome_IF
                      

                      Hier noch etwas Background zum nachlesen:
                      https://gist.github.com/AlCalzone/d14b854b69ce5e8a03718336cc650a95#

                      hanssH Offline
                      hanssH Offline
                      hanss
                      schrieb am zuletzt editiert von
                      #13

                      @alcalzone
                      Ich habe übersehen, den usernamen u. password unkenntlich zu machen.
                      Könntest Du das bitte machen?
                      Danke.

                      AlCalzoneA 1 Antwort Letzte Antwort
                      0
                      • hanssH hanss

                        @alcalzone
                        Ich habe übersehen, den usernamen u. password unkenntlich zu machen.
                        Könntest Du das bitte machen?
                        Danke.

                        AlCalzoneA Offline
                        AlCalzoneA Offline
                        AlCalzone
                        Developer
                        schrieb am zuletzt editiert von
                        #14

                        @hanss Erledigt

                        Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

                        hanssH 1 Antwort Letzte Antwort
                        0
                        • AlCalzoneA AlCalzone

                          @hanss Erledigt

                          hanssH Offline
                          hanssH Offline
                          hanss
                          schrieb am zuletzt editiert von
                          #15

                          @alcalzone
                          Danke, da ist noch eines vor 23 Stunden

                          AlCalzoneA 1 Antwort Letzte Antwort
                          0
                          • hanssH hanss

                            @alcalzone
                            Danke, da ist noch eines vor 23 Stunden

                            AlCalzoneA Offline
                            AlCalzoneA Offline
                            AlCalzone
                            Developer
                            schrieb am zuletzt editiert von
                            #16

                            @hanss check!

                            Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

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


                            Support us

                            ioBroker
                            Community Adapters
                            Donate

                            773

                            Online

                            32.5k

                            Benutzer

                            81.8k

                            Themen

                            1.3m

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

                            • Du hast noch kein Konto? Registrieren

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