Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. await is only valid in async functions ...

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    await is only valid in async functions ...

    This topic has been deleted. Only users with topic management privileges can see it.
    • Codierknecht
      Codierknecht Developer Most Active @warhammer73 last edited by

      @warhammer73 sagte in await is only valid in async functions ...:

      Damit sich das Thermostat aber keinen Wolf dreht und das Script ständig Last erzeugt, soll die Regelung zwischen Ist und Soll nur zyklisch passieren (Daher der 5min Timeout)

      Hast Du ein Thermostat oder ein Ventil + Thermometer?
      Wenn ich meinem Thermostat sage "mach mal 22°C" dann öffnet es. Und zwar so lange, bis das Thermometer (intern oder extern) sagt "22°C erreicht". Das macht das Ding völlig selbsttätig. Ob es sich dabei "einen Wolf dreht" ist mir völlig Schnuppe.
      Ändert jemand zwischendurch am Thermostat die Solltemperatur bleibt es entweder länger auf oder regelt früher ab. Auch ganz alleine ... ohne eine Zeile Code.
      Der Code kommt erst für die automatische Steuerung der Temperatur im Tag- bzw. Nachbetrieb ins Spiel. Der sagt per Schedule um 06:00 Uhr "stelle die Solltemperatur von 12 °C auf 22°C. Und schwupps ... öffnet sich das Ventil am Thermostat, um den Raum auf 22 °C zu heizen.
      Mein Thermostat regelt jedenfalls von alleine 😉

      W 1 Reply Last reply Reply Quote 0
      • W
        warhammer73 @warhammer73 last edited by

        @warhammer73

        ... so, die Idee mit dem Datum anstatt sleep funktioniert. Im Code sieht das dann erstmal so aus:
        Trigger anlegen ausserhalb der Hauptschleife (Erstmal nur für ein Zimmer zum testen)
        new_temperature_value ist jetzt eine globale Variable damit die auch hier ausgewertet werden kann

        for (let i=0; i<1; i++) {
            console.log("Create Trigger");
            let room = deviceName[i];
            on({id: [folderName + "." + room + ".Target_temperature_manual", "alias.0." + room + ".Thermostat.SET"], change: "any" }, function (obj) 
            { 
                    if (getState("alias.0." + room + ".Thermostat.SET").val != new_temperature_value) { 
                        console.log ("Datapoint manual changed");
                        setState(folderName + "." + room + ".Temperature_manual_changed",true,true);
                        changeDate=new Date();
                    }    
            });
        }
        

        In der Hauptschleife prüfe ich jetzt ob der DP für eine manuelle Änderung auf true steht und ob die Zeit überschritten wurde die das Script die Temperatur nicht überschreiben soll.
        Wenn sie überschritten ist, wird der DP auf false gesetzt und nur wenn er auf false steht bekommt das Thermostat einen neuen Wert geschrieben.

            if (getState(folderName + "." + room + ".Temperature_manual_changed").val == true && (new Date().getTime() - changeDate.getTime()) > locktime) {
                console.log("Loop manual changed and locktime reached");
                setState(folderName + "." + room + ".Temperature_manual_changed",false, true);
            }
            if (getState(folderName + "." + room + ".Temperature_manual_changed").val == false) {
                console.log ("SetTemperatur on Thermostat: " + new_temperature_value + " based on Room temperature " + current_room_temperature + ", Thermostat_temparature " + getState("alias.0." + room + ".Thermostat.ACTUAL").val +" and target temperature " + target_temperature);
                setState("alias.0." + room + ".Thermostat.SET", new_temperature_value, false);  
            }
            console.log ("Sleep for " + sleeptime + " sec");
            await sleep(sleeptime);
        

        ... zwei Sachen dabei gelernt:
        a) Wenn man einen DP abfragt, sollte man auch sicher gehen das er entweder den richtigen Wert beim erstmaligen Scriptlauf hat, oder dafür sorgen das das Script mit allen Eventualitäten umgehen kann. 🙂
        b) Die Variante "Kann ich ja dann alles in der Schleife machen" funktioniert natürlich nicht, denn Änderungen werden erst nach Ablauf von sleep verarbeitet. Aber das sollte sich ja mit einer aufgerufenen Funktion ändern lassen...

        1 Reply Last reply Reply Quote 0
        • W
          warhammer73 @Codierknecht last edited by

          @codierknecht said in await is only valid in async functions ...:

          @warhammer73 sagte in await is only valid in async functions ...:

          Damit sich das Thermostat aber keinen Wolf dreht und das Script ständig Last erzeugt, soll die Regelung zwischen Ist und Soll nur zyklisch passieren (Daher der 5min Timeout)

          Hast Du ein Thermostat oder ein Ventil + Thermometer?
          Wenn ich meinem Thermostat sage "mach mal 22°C" dann öffnet es. Und zwar so lange, bis das Thermometer (intern oder extern) sagt "22°C erreicht". Das macht das Ding völlig selbsttätig. Ob es sich dabei "einen Wolf dreht" ist mir völlig Schnuppe.
          Ändert jemand zwischendurch am Thermostat die Solltemperatur bleibt es entweder länger auf oder regelt früher ab. Auch ganz alleine ... ohne eine Zeile Code.
          Der Code kommt erst für die automatische Steuerung der Temperatur im Tag- bzw. Nachbetrieb ins Spiel. Der sagt per Schedule um 06:00 Uhr "stelle die Solltemperatur von 12 °C auf 22°C. Und schwupps ... öffnet sich das Ventil am Thermostat, um den Raum auf 22 °C zu heizen.
          Mein Thermostat regelt jedenfalls von alleine 😉

          Thermostat mit internem Thermometer + externes Thermometer. Ja, ich kann dem Thermometer sagen "Mache 22°" - Nur was dann am anderen Ende vom Zimmer ankommt hat damit nichts zu tun.
          Ja, ich hätte auch teure Bosch Thermometer kaufen können die dann automatisch mit dem Thermostat gesprochen hätten.
          Ob sich das Thermostat einen Wolf dreht sollte Dir nicht Schnuppe sein - Geht nämlich massiv auf die Batterie.
          Selbst Tag/Nacht und das pro Tag kann die Bosch App alleine.

          ... was sie nicht kann:
          Abhängig von Homeoffice Kalendern die Temperatur steuern
          Mit zwei Heizkörpern und einem Innenthermometer unterschiedliche Temperaturen an den Thermostaten einstellen
          Bei "Fenster auf" nur die Heizung runterregeln die in Fensternähe ist und erst ab einem längeren Abfall auch die andere Heizung abdrehen
          ... und was so gar keine Thermostatregelung von alleine kann: Wenn es kalt ist, aber die PV Anlage genug Energie hat nicht per Heizkörper sondern per Splitklima heizen, es sei denn es ist jemand im Homeoffice.

          Codierknecht 1 Reply Last reply Reply Quote 0
          • Codierknecht
            Codierknecht Developer Most Active @warhammer73 last edited by

            @warhammer73
            Also ich habe die Zieltemperatur am HM Wandthermostat mit der Zieltemperatur des ZigBee-Thermostaten gekoppelt.
            Der ZigBee Fenstersensor liefert dem HM den Status des Fensters.
            Heating-Control steuer das Ganze über die Zeit.
            Funktioniert einwandfrei und reicht mir völlig.

            Bei der Masse Deiner Anforderungen bin ich raus ... da stehen für mich Aufwand und Nutzen nicht im richtigen Verhältnis. Und: Je komplexer ein System, desto eher geht etwas schief wenn in dem filigranen Getriebe etwas knirscht.

            W 1 Reply Last reply Reply Quote 0
            • W
              warhammer73 @Codierknecht last edited by

              @codierknecht
              Naja, aus WAF Gründen brauchte ich leise Thermostate - Leiser wie die Bosch habe ich nicht gefunden, die spielen aber ohne iobroker und co. eben nur mit Bosch.

              So schlimm ist das meiste gar nicht - javascript mag nur vieles anders als die Sachen die ich gewohnt bin und da muss man manchmal um ein paar Ecken denken. 🙂

              Codierknecht 1 Reply Last reply Reply Quote 0
              • W
                warhammer73 last edited by

                @Asgothian , @Paul53, @Codierknecht:
                Danke für Eure Hinweise und Ideen.

                Das ganze sieht jetzt so aus:

                function SetTemperature(room) {
                    let locktime = 3600;
                    locktime = locktime * 1000;
                    setState(folderName + "." + room + ".Roomtemperature", current_room_temperature, true);
                    setState(folderName + "." + room + ".Target_temperature", parseInt(target_temperature), true); 
                    setState(folderName + "." + room + ".Thermostat_temperature", getState("alias.0." + room + ".Thermostat.ACTUAL").val, true);
                    setState(folderName + "." + room + ".Thermostat", parseInt(new_temperature_value), true);
                    setState(folderName + "." + room + ".Lastchange", new Date().toLocaleString(), true); 
                    console.log ("Manual changed: " + getState(folderName + "." + room + ".Temperature_manual_changed").val);
                    console.log ("Window: " + getState("alias.0." + room + ".Fensterkontakt.ACTUAL").val);
                    if (getState("alias.0." + room + ".Fensterkontakt.ACTUAL").val == false) {
                        console.log ("Set temperature to minimum");
                        setState("alias.0." + room + ".Thermostat.SET", min_temperature, true); 
                    }   else if (getState(folderName + "." + room + ".Temperature_manual_changed").val == true && (new Date().getTime() - changeDate.getTime()) > locktime) {
                        console.log("Loop manual changed and locktime reached");
                        setState(folderName + "." + room + ".Temperature_manual_changed",false, true);
                    }   else if (getState(folderName + "." + room + ".Temperature_manual_changed").val == false) {
                        console.log ("SetTemperatur on Thermostat: " + new_temperature_value + " based on Room temperature " + current_room_temperature + ", Thermostat_temparature " + getState("alias.0." + room + ".Thermostat.ACTUAL").val +" and target temperature " + target_temperature);
                        setState("alias.0." + room + ".Thermostat.SET", new_temperature_value, true);  
                    }
                }
                
                
                // Trigger für manuelle Änderungen anlegen, Testweise nur ein Raum
                for (let i=0; i<1; i++) {
                    console.log("Create Trigger");
                    let room = deviceName[i];
                    on({id: [folderName + "." + room + ".Target_temperature_manual", "alias.0." + room + ".Thermostat.SET"], change: "any" }, function (obj) 
                    { 
                            if (getState("alias.0." + room + ".Thermostat.SET").val != new_temperature_value) { 
                                console.log ("Datapoint manual changed");
                                setState(folderName + "." + room + ".Temperature_manual_changed",true,true);
                                changeDate=new Date();
                                SetTemperature(room);
                            }    
                    });
                    on({id: ["alias.0." + room + ".Fensterkontakt.ACTUAL"], change: "any" }, function (obj) 
                    { 
                            if (getState("alias.0." + room + ".Fensterkontakt.ACTUAL").val == true) { //geschlossen
                                console.log ("Window Closed");
                                SetTemperature(room);
                            } else {
                                console.log ("Window Opened");
                                SetTemperature(room);
                            }   
                    });
                }
                
                
                
                while (1) {
                   ... kleine Magie zur Ist Temperaturberechnung. ;)
                    SetTemperature(room);
                    console.log ("Sleep for " + sleeptime + " sec");
                    await sleep(sleeptime);   
                } 
                
                

                ... das Einzige was jetzt noch fehlt ist das beim Fenster schliessen der alte Wert wiederhergestellt wird - Aber erstmal morgen alles durchtesten.

                1 Reply Last reply Reply Quote 0
                • Codierknecht
                  Codierknecht Developer Most Active @warhammer73 last edited by

                  @warhammer73 sagte in await is only valid in async functions ...:

                  Naja, aus WAF Gründen brauchte ich leise Thermostate - Leiser wie die Bosch habe ich nicht gefunden, die spielen aber ohne iobroker und co. eben nur mit Bosch.

                  Die Fritz!Dect 301 sind ziemlich leise - zumindest im Vergleich mit Aqara E1.
                  Mich stört allerdings die Reaktionszeit von bis zu 15 Minuten. Darum gebe ich die wieder ab.
                  https://forum.iobroker.net/topic/61778/verkaufe-2x-fritz-dect-301-heizkörperthermostat

                  W 1 Reply Last reply Reply Quote 0
                  • W
                    warhammer73 @Codierknecht last edited by

                    @codierknecht
                    Netter Werbungsversuch 😉

                    1 Reply Last reply Reply Quote 0
                    • Codierknecht
                      Codierknecht Developer Most Active @warhammer73 last edited by

                      @warhammer73 sagte in await is only valid in async functions ...:

                      Es gibt auch noch einen Fenster offen Sensor auf dessen Trigger natürlich das Thermostat auf min gehen soll und wenn Fester zu wieder auf den alten Wert.

                      Nur so als Anmerkung, weil ich diese Idee auch schon hatte:
                      Dein Zeitplan sagt: Zwischen 07:00 und 16:00 Uhr => Komforttemperatur (z.B. 22°C).
                      Um 15:55 Uhr macht jemand das Fenster auf => Runter auf Minimum und alten Wert merken.
                      Wird jetzt um 16:05 Uhr das Fenster geschlossen wird, würde ein einfaches "wieder auf den alten Wert" den Zeitplan aushebeln. Muss also irgendwie berücksichtigt werden.

                      W 1 Reply Last reply Reply Quote 0
                      • W
                        warhammer73 @Codierknecht last edited by

                        @codierknecht
                        Richtig, ist aber ein Punkt den ich an der Stelle ignoriere.
                        Warum? Die Schleife die alle X Minuten (Aktuell 10) einen neuen Wert würfelt berücksichtigt den Zeitplan.
                        Der "falsche" Wert greift also maximal für die Schlafzeit des Scriptes. Für mich verkraftbar.

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

                        Support us

                        ioBroker
                        Community Adapters
                        Donate

                        837
                        Online

                        31.8k
                        Users

                        80.0k
                        Topics

                        1.3m
                        Posts

                        5
                        26
                        916
                        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