Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. Heizkreisregelungen - JS

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    Heizkreisregelungen - JS

    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      sound31 last edited by

      Überleitung aus Thema : "Raumtemperaturregelung mit Blockly"

      http://forum.iobroker.net/viewtopic.php?f=21&t=9214

      @paul53

      Deine Änderungen des Skript's habe ich bereits übernommen.

      Denn Praxistest kann ich heute Abend machen nach dem einbau der neuen

      KNX-IP-Schnittstelle.

      Grüße, Andy.

      1 Reply Last reply Reply Quote 0
      • paul53
        paul53 last edited by

        @sound31:

        Überleitung aus Thema : Vorlauftemperatur und Witterungsgeführte Heizkreisregelung. `
        Die Heizkurve (Aussentemperaturabhängiger VL-Temperatur-Sollwert) kan mit folgendem Beispiel-Skript (Raumtemperatursollwerte aus 4 Räumen) berechnet werden:

        // Heizkurve: Aussentemperaturabhängiger VL-Temperatur-Sollwert
        
        // Datenpunkt-IDs
        const idAT = '...'; // Außentemperaturfühler
        const idVL = '...'; // DP für Vorlauftemperatur-Sollwert
        const idRaum1Soll = '...'; // Raumsollwert
        const idRaum2Soll = '...'; // Raumsollwert
        const idRaum3Soll = '...'; // Raumsollwert
        const idRaum4Soll = '...'; // Raumsollwert
        
        const HFExp = 1.3;         // Heizflächenexponent
        const Steilheit = 2.7;     // Steilheit der Heizkurve
        const deltaAufheiz = 2;    // Fusspunktanhebung während Aufheizen in K
        const dauerAufheiz = 90;   // Aufheizdauer in Minuten
        
        // Variablen werden bei Skriptstart initialisiert
        var raum1Soll = getState(idRaum1Soll).val;
        var raum2Soll = getState(idRaum2Soll).val;
        var raum3Soll = getState(idRaum3Soll).val;
        var raum4Soll = getState(idRaum4Soll).val;
        var at = getState(idAT).val; // Aussentemperatur in °C
        
        var fp; // Fußpunkt der Heizkurve in °C
        var aufheiz = 0;  // Fusspunktanhebung in K
        var timer = null; // Timer für Aufheizdauer
        
        function VLSoll() {
        	var vl = 0;
        	if(at < fp) vl = fp + Steilheit * Math.pow(fp - at, 1 / HFExp);
        	setState(idVL, Math.round(10 * vl) / 10, true);
        }
        
        function fusspunkt() {
        	fp = Math.max(raum1Soll, raum2Soll, raum3Soll, raum4Soll) + aufheiz;
        	VLSoll();
        }
        
        function Aufheizen() {
        	aufheiz = deltaAufheiz;
        	if(timer) clearTimeout(timer);
        	timer = setTimeout(function() {
        		aufheiz = 0;
        		fusspunkt();
        	}, 60000 * dauerAufheiz);
        }
        
        fusspunkt(); // Skriptstart
        
        on(idAT, function(dp) {
        	at = dp.state.val;
        	VLSoll();
        });
        
        on(idRaum1Soll, function(dp) {
        	raum1Soll = dp.state.val;
        	if(raum1Soll - dp.oldState.val > 2) Aufheizen();
        	fusspunkt();
        });
        
        on(idRaum2Soll, function(dp) {
        	raum2Soll = dp.state.val;
        	if(raum2Soll - dp.oldState.val > 2) Aufheizen();
        	fusspunkt();
        });
        
        on(idRaum3Soll, function(dp) {
        	raum3Soll = dp.state.val;
        	if(raum3Soll - dp.oldState.val > 2) Aufheizen();
        	fusspunkt();
        });
        
        on(idRaum4Soll, function(dp) {
        	raum4Soll = dp.state.val;
        	if(raum4Soll - dp.oldState.val > 2) Aufheizen();
        	fusspunkt();
        });
        
        
        1 Reply Last reply Reply Quote 0
        • S
          sound31 last edited by

          Hallo,

          Der Datenpunkt:

          "const idVL = '…'; // DP für Vorlauftemperatur-Sollwert"

          ist das ein Vorgabe Datenpunkt oder der des Fühler's nach dem Mischer?

          1 Reply Last reply Reply Quote 0
          • paul53
            paul53 last edited by

            @sound31:

            "const idVL = '…'; // DP für Vorlauftemperatur-Sollwert"

            ist das ein Vorgabe Datenpunkt oder der des Fühler's nach dem Mischer? `
            Das ist ein Datenpunkt zur Vorgabe des Sollwertes. Das Skript enthält nicht den PI-Regler, der aus Soll- und Istwert das Stellsignal berechnet.

            Ein http://www.iobroker.net/docu/?page_id=3725&lang=de ist dokumentiert. Für eine Vorlauftemperatur-Regelung müssen die Regelparameter angepasst werden.

            // P-Band in K, Nachstellzeit in s
            const Xp = 20;
            const Tn = 120;
            
            1 Reply Last reply Reply Quote 0
            • paul53
              paul53 last edited by

              Das PI-Regler-Skript, angepasst.

              // PI-Regler Vorlauftemperatur Heizung
              
              // P-Band in K, Nachstellzeit in s
              const Xp = 20;
              const Tn = 120;
              
              const idx = '...'; // Messwert Vorlauftemperatur
              const idw = 'javascript.0...'; // Sollwert aus Heizkurve
              const idy = 'javascript.0...'; // Stellsignal 0...100 %
              
              const PI = require('pi-controller');
              const pi = new PI(Xp, Tn); 
              
              // Variablen werden bei Skriptstart initialisiert
              var x = getState(idx).val;  // Istwert in °C
              var w = getState(idw).val;  // Sollwert in °C
              
              function control() {
                 setState(idy, pi.Control(w - x)); // Stellsignal
              }
              
              control();  // Script start
              
              on(idx, function(dp) {
                 x = dp.state.val;
                 control();
              });
              
              on(idw, function(dp) {
                 w = dp.state.val;
                 control();
              });   
              
              var timer = null;
              if (Tn) {
                 timer = setInterval(control, 250 * Tn );
              } 
              else {
                 if (timer) {
                    clearInterval(timer);
                    timer = null;
                 }
              }
              

              Das Stellsignal könnte direkt einen Analogausgang für ein 0-10 V Stellventil steuern. Da aber ein 3-Punkt-Stellantrieb vorhanden ist, muss die Funktion eines analogen Stellantriebs in einem weiteren Skript nachgebildet werden.

              1 Reply Last reply Reply Quote 0
              • S
                sound31 last edited by

                Hallo,

                Danke für die viele Hilfe.

                Leider muss ich kurz Unterbrechen und erst versuchen die KNX Kommunikation

                korrekt zum laufen zu bringen.

                Es werden nicht alle Sensoren richtig angezeigt!

                Grüße, Andy

                1 Reply Last reply Reply Quote 0
                • S
                  sound31 last edited by

                  Hallo paul53,

                  ich hoffe das ich mit dem Datenpunkt Vorlauftemperatur richtig liege..

                  hier habe ich den Fühler genommen der nach dem Mischer im Heizkreis OG liegt.

                  Beim Mischer handelt es sich ja bei mir um einen 230V Motorantrieb wobei

                  die Drehrichtungen Öffnen,Schließen mit zwei getrennten Wicklungen funktionieren.

                  Diese kann ich über KNX getrennt ansprechen.

                  (Sind Mechanisch verriegelt)

                  Grüße, Andy

                  1 Reply Last reply Reply Quote 0
                  • paul53
                    paul53 last edited by

                    @sound31:

                    ch hoffe das ich mit dem Datenpunkt Vorlauftemperatur richtig liege..

                    hier habe ich den Fühler genommen der nach dem Mischer im Heizkreis OG liegt. `
                    Ja, der Fühler hinter dem Mischer muss die Vorlauftemperatur des Mischkreises messen.

                    1 Reply Last reply Reply Quote 0
                    • paul53
                      paul53 last edited by paul53

                      Hier noch ein Skript (nicht getestet) zur Ansteuerung des 3-Punkt-Antriebs (Mischer)

                      // 3-Punkt-Ansteuerung aus Stellsignal
                      
                      const Laufzeit = 150;  // Laufzeit des Stellantriebs in s
                      const Stellmax = 100;  // max. Stellsignal (%)
                      const minMove = 2;     // mindest Positionsänderung des Antriebs (in %)
                      const idy = 'javascript.0...';  // Datenpunkt-ID Stellsignal
                      const idAuf = '...';  // Datenpunkt-ID Antrieb Richtung Auf
                      const idZu = '...';   // Datenpunkt-ID Antrieb Richtung Zu
                      
                      var faktor = 1000 * Laufzeit / Stellmax;  // Faktor ms/%
                      var lastPos = 0;   // letzte Position (Stellsignal)
                      var motor = true;  // Indikator: Antrieb in Bewegung
                      
                      function move(pos) {
                      	if(!motor) {
                      		if(pos - lastPos > minMove) {
                      			setState(idAuf, true);
                      			motor = true;
                      			if(timer) clearTimeout(timer);
                      			timer = setTimeout(function() {
                      				setState(idAuf, false);
                      				motor = false;
                      			}, faktor * (pos - lastPos));
                      			lastPos = pos;
                      		}
                      		else if(lastPos - pos > minMove) {
                      			setState(idZu, true);
                      			motor = true;
                      			var deltaPos = lastPos - pos;
                      			if(pos === 0) deltaPos = deltaPos + 10;  // Synchronistation "Zu"
                      			if(timer) clearTimeout(timer);
                      			timer = setTimeout(function() {
                      				setState(idZu, false);
                      				motor = false;
                      			}, faktor * deltaPos);
                      			lastPos = pos;
                      		}	
                      	}
                      }
                      
                      on(idy, function(dp) {
                      	move(dp.state.val);
                      });
                      
                      // Bei Skriptstart fährt Antrieb erst auf Position 0 (Zu)
                      setState(idAuf, false); 
                      setState(idZu, true);
                      var timer = setTimeout(function() {
                          setState(idZu, false);
                          motor = false;
                          move(getState(idy).val); // Fahren in Sollposition
                      }, 1000 * (Laufzeit + 10));
                      

                      EDIT: Skriptstart erweitert auf Fahren in Sollposition

                      S 1 Reply Last reply Reply Quote 0
                      • S
                        sound31 last edited by

                        Hallo Paul53,

                        Vorab einmal Herzlichen Dank für deine Hilfe das ist echt der Wahnsinn, Danke.

                        Die beiden Heizkreise der Fußbodenheizung die fertig sind (Flur und Küche im EG)

                        habe ich jetzt von der bestehenden Steuerung getrennt und mit dem Java-Protokoll in Betrieb genommen.

                        Jeweils in Unterordnern einzeln, auch das Script zur Berechnung der Heizkurve läuft bereits.

                        Mit den eingestellten Sollwerten bekomme ich einen Rückwert von dz. 47,2°C

                        (wie im Bild dargestellt)
                        4002_screenshot.13.jpg
                        Ich hoffe das ist so richtig.

                        Da die Ist-Temperatur in der Küche (infolge vom Kochen usw.) immer etwas höher liegt habe

                        ich zum Testen die Solltemperatur höher gestellt um zu sehen ob das so Funktioniert, das tut es!

                        Stimmt der Datenpunkt zum Stellsignal so? (Bild 2)
                        4002_screenshot.16.jpg

                        Grüße, Andy

                        1 Reply Last reply Reply Quote 0
                        • paul53
                          paul53 last edited by

                          Du hast die Datenpunkte unter javascript.0.scriptEnabled erstellt. Das solltest Du ändern !

                          Erstelle die Datenpunkte direkt unter javascript.0. Beispiel: Name "Heizung.Stellsignal-HK-OG" entspricht ID "javascript.0.Heizung.Stellsignal-HK-OG".

                          > Stimmt der Datenpunkt zum Stellsignal so? (Bild 2)
                          Nein, der Datenpunkt muss vom Typ "Zahl" mit min: 0, max: 100 und unit: "%" sein.

                          1 Reply Last reply Reply Quote 0
                          • S
                            sound31 last edited by

                            In den Script's für die Fußbodenheizung habe ich jetzt jeweils eine Variable

                            für die Anforderung der Pumpe gesetzt:

                            var pump = "javascript.0.FBH-Pumpe-1"/*FBH-Pumpe-1*/;
                            
                            

                            diese wird mit den Ventilen eingeschalten.

                            Danach ein Script für die Pumpeneinschaltung:

                            // Ansteuerung Pumpe
                            // für Fußbodenheizungen
                            
                            var pump1 = "javascript.0.FBH-Pumpe-1"/*FBH-Pumpe-1*/;
                            var pump2 = "javascript.0.FBH-Pumpe-2"/*FBH-Pumpe-2*/;
                            var pump = "knx.0.Aktoren.Heizung-Technik.HK-Verteiler_EG_-_Relais_1"/*HK-EG-Pumpe*/;
                            
                            function control() {
                                if (pump1 == 1 || pump2 == 1)
                                {
                                    setState(pump, 1);
                                }
                                else if (pump1 === 0 && pump2 === 0)
                                {
                                    setState(pump, 0);
                                }
                            } 
                            
                            

                            Ich hoffe das ist so korrekt.

                            Die Datenpunkte habe ich so angelegt:
                            4002_screenshot.20.jpg
                            4002_screenshot.21.jpg

                            1 Reply Last reply Reply Quote 0
                            • paul53
                              paul53 last edited by

                              @sound31:

                              Ich hoffe das ist so korrekt. `
                              Leider nicht. Die Pumpen-Datenpunkte sollten vom Typ "boolean" (Logikwert oder Schalter) sein. Das Skript funktioniert so nicht.

                              // Ansteuerung Pumpe
                              // für Fußbodenheizungen
                              
                              var idpump1 = "javascript.0.FBH-Pumpe-1"/*FBH-Pumpe-1*/;
                              var idpump2 = "javascript.0.FBH-Pumpe-2"/*FBH-Pumpe-2*/;
                              var idpump = "knx.0.Aktoren.Heizung-Technik.HK-Verteiler_EG_-_Relais_1"/*HK-EG-Pumpe*/;
                              
                              // Initialisierung bei Skriptstart
                              var pump1 = getState(idpump1).val;
                              var pump2 = getState(idpump2).val;
                              
                              function control() {
                                  if (pump1 || pump2)
                                  {
                                      setState(idpump, true);
                                  }
                                  else
                                  {
                                      setState(idpump, false);
                                  }
                              }
                              
                              // Skriptstart
                              control();
                              
                              // Auf Änderung von Pumpe1 reagieren
                              on(idpump1, function(dp) {
                                  pump1 = dp.state.val;
                                  control();
                              });
                              
                              // Auf Änderung von Pumpe 2 reagieren
                              on(idpump2, function(dp) {
                                  pump2 = dp.state.val;
                                  control();
                              });
                              
                              
                              1 Reply Last reply Reply Quote 0
                              • paul53
                                paul53 last edited by

                                Anmerkung: Die Trägheit der thermoelektrischen Stellantriebe (brauchen ca. 5 Minuten für gesamten Hub) sollte beachtet werden. Die Pumpe sollte also mit ca. 3 Minuten Verzögerung gaschaltet werden.

                                var timer = null;
                                
                                function control() {
                                    if(timer) clearTimeout(timer);
                                    if (pump1 || pump2) {
                                        timer = setTimeout(function() {
                                            setState(idpump, true);
                                        }, 180000);  // 3 Minuten Verzögerung
                                    }
                                    else {
                                        timer = setTimeout(function() {
                                            setState(idpump, false);
                                        }, 180000);    
                                   }
                                }
                                
                                1 Reply Last reply Reply Quote 0
                                • S
                                  sound31 last edited by

                                  Stimmt die Schaltung im Script FBH so?

                                  // PI-Regler Fussbodenheizung mit PWM-Ansteuerung
                                  // für FBH Flur EG
                                  // P-Band in K, Nachstellzeit in s, PWM-Periode in Intervallen (Minuten)
                                  var Xp = 2;
                                  var Tn = 3600;
                                  var pwm = 100; //* PWM Zeit verlängert
                                  
                                  var xid = "knx.0.Sensoren.Erdgeschoss.Temp-Sensor_Küche_EG"/*Temp-Sensor Küche EG*/;
                                  var wid = "javascript.0.Sollwert-Küche-EG"/*Sollwert-Küche-EG*/;
                                  var yid = "knx.0.Aktoren.Heizung-Technik.HK-Verteiler_EG_-_Solid_Stade_Relais_1"/*SSR-Küche-EG*/;
                                  var pump = "javascript.0.FBH-Pumpe-2"/*FBH-Pumpe-2*/;
                                  var n = 0;  // Intervallzähler
                                  
                                  var  PI = require('pi-controller');
                                  
                                  var pi = new PI(Xp, Tn); 
                                  pi.setOutputMax(pwm);   // default: OutputMax = 100
                                  
                                  // Abfrage für Sommer/Winter noch einfugen
                                  
                                  function control() {
                                    var x = getState(xid).val;    // Istwert in °C
                                    var w = getState(wid).val;    // Sollwert in °C
                                    var y = pi.Control(w - x);    // Stellsignal
                                    n++;
                                    if (n >= pwm) n = 0;
                                     if (n < 8 && y > 0)           // Mindesteinschaltdauer: 8 Intervalle
                                      {   setState(yid, 1);
                                          setState(pump, 1);		// Pumpe Einschalten
                                      }
                                    else if (n >= 8 && y <= n)    // Zwei Ventile werden geschalten
                                      {   setState(yid, 0);
                                          setState(pump, 0);		// Pumpe Ausschalten
                                      }  
                                  }
                                  
                                  control();  // Script start
                                  
                                  setInterval(control, 60000 );  // Intervall: 1 Minute
                                  
                                  
                                  1 Reply Last reply Reply Quote 0
                                  • paul53
                                    paul53 last edited by

                                    Die Intervall-Zeit solltest Du auf die Hälfte verringern.

                                    setInterval(control, 30000 );  // Intervall: 0,5 Minuten
                                    

                                    Die Datenpunkte zur Pumpenanforderung werden nicht benötigt, denn im Pumpenskript können die Ventildatenpunkte direkt ausgewertet werden (schalten identisch).

                                    Sind die KNX-Schalt-Datenpunkte vom Typ "boolean" mit den Werten false/true oder sind sie vom Typ Zahl mit den Werten 0/1 ?

                                    1 Reply Last reply Reply Quote 0
                                    • S
                                      sound31 last edited by

                                      Die Datenpunkte sind Logikwert, switch so wurden sie eingelesen vom

                                      KNX Adapter.
                                      4002_screenshot.13.jpg
                                      deswegen habe ich die Ursprünglichen Werte true/false auf 0/1 geändert.

                                      Am WE möchte ich nochmal alle Datenpunkte von der KNX-seite prüfen um

                                      sicher zu gehen das auch alle richtig angezeigt werden.

                                      1 Reply Last reply Reply Quote 0
                                      • S
                                        sound31 last edited by

                                        > Die Datenpunkte zur Pumpenanforderung werden nicht benötigt, denn im Pumpenskript können die Ventildatenpunkte direkt ausgewertet werden (schalten identisch).
                                        müsste ich dann im Pumpenscript nicht die ID's der Ventile bei den Variablen einfügen

                                        var idpump1 = "javascript.0.FBH-Pumpe-1"/*FBH-Pumpe-1*/;
                                        var idpump2 = "javascript.0.FBH-Pumpe-2"/*FBH-Pumpe-2*/;
                                        
                                        
                                        1 Reply Last reply Reply Quote 0
                                        • paul53
                                          paul53 last edited by

                                          @sound31:

                                          Die Datenpunkte sind Logikwert, switch so wurden sie eingelesen vom KNX Adapter. `
                                          Logikwert und min: 0, max: 1 sind ein Widerspruch. Diesbezüglich wurde der Adapter schlampig programmiert. Dann kommt es darauf an, auf welche Werte reagiert wird.
                                          @sound31:

                                          müsste ich dann im Pumpenscript nicht die ID's der Ventile bei den Variablen einfügen `
                                          Richtig.

                                          1 Reply Last reply Reply Quote 0
                                          • S
                                            sound31 last edited by

                                            > Logikwert und min: 0, max: 1 sind ein Widerspruch. Diesbezüglich wurde der Adapter schlampig programmiert. Dann kommt es darauf an, auf welche Werte reagiert wird.
                                            Sollte ich das in den Einstellungen ändern, Die Ventile und auch die Pumpen werden richtig geschalten.

                                            Dann kann ich im FBH-Script die Declaration der Variablen und auch das Ein und Ausschalten dieser entfernen.

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            884
                                            Online

                                            31.7k
                                            Users

                                            79.8k
                                            Topics

                                            1.3m
                                            Posts

                                            4
                                            47
                                            6136
                                            Loading More Posts
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            Community
                                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                            The ioBroker Community 2014-2023
                                            logo