Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. Flexibler Schedule für Rolladensteuerung über Jarvis steuern

    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

    Flexibler Schedule für Rolladensteuerung über Jarvis steuern

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

      Hi zusammen,

      ich habe versucht ein Script zu schreiben, dass mir ermöglicht die Rolladen in jedem Raum meines Hauses über mein Jarvis Dashboard zu konfigurieren. Ich wollte keine statischen Zeiten, besser gesagt nicht NUR statische Zeiten um meine Rolladen zu schalten.

      Zielvorstellung ist, für jeden Raum eine default Zeit zu haben wann die Rolladen hoch und runter fahren sollen, die aber durch die Eingabe in einem extra Feld überschrieben werden kann. (in meinem Codesnippet ist das Überschreiben noch nicht drin, es soll erstmal so zuverlässig funktionieren)

      e766c8a6-103f-4a9b-b619-e0affb3b9ee3-image.png

      var ObjectID, j, k, ReadValues, Crondays, formerstate, formerformerstate, openh, openm, closeh, closem, time, openschedule, closeschedule;
      
      // Read the description and the value from the object --> Ob die Knöpfe für die Tage gedrückt sind oder nicht
      async function Read_Info(ObjectID) {
          let desc = getObject(ObjectID).common.desc;
          let value = getState(ObjectID).val;
          return [desc,value];
      }
      
      // Trigger
      on({id: [].concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Mo']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Tu']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_We']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Th']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Fr']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Sa']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Su']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Default_Schedule_Close']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Default_Schedule_Open']), change: "ne"}, async function (obj) {
      // Put the list together for the for loop to build the cron value for the dates
          var j_list = ['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Su', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Mo', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Tu', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_We', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Th', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Fr', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Sa'];
      // Put the list together for the for loop to build the cron value for the hours
          var ObjOpen = 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Default_Schedule_Open';
          var ObjClose = 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Default_Schedule_Close';
      
      // Resetting some variables
          Crondays = "";
          formerstate = "";
          formerformerstate = "";
      
      //Loop to build the cron value for the dates based on j_list
          for (var j_index in j_list) {
              j = j_list[j_index];
              ReadValues = await Read_Info(j);
         
              if (j_index == '0' && ReadValues[1]){
                  Crondays = "0";
                  formerstate = ReadValues[1];
                  continue;
              }
         
              if (j_index >= "1"){
                  if(ReadValues[1] && formerstate && !(formerformerstate)){
                      Crondays += ("," + j_index)
                  }
                  if(ReadValues[1] && formerformerstate && formerstate){
                      Crondays = Crondays.replace(/..$/, "-" + j_index);
                  }
                  if(ReadValues[1] && !(formerstate)){
                      if(Crondays == ""){
                          Crondays += j_index
                      }else{
                          Crondays += ("," + j_index)
                      }
                  }
              }
              if(Crondays == "0-6"){Crondays = "*"}
              formerformerstate = formerstate;
              formerstate = ReadValues[1];
          }
      
          ReadValues = await Read_Info(ObjOpen);
          time = ReadValues[1].split(":");
          if(time[0].charAt(0) == 0){
              openh = time[0].charAt(1)
          }else{
              openh = time[0]
          }
          if(time[1].charAt(0) == 0){
              openm = time[1].charAt(1)
          }else{
              openm = time[1]
          }
      
          ReadValues = await Read_Info(ObjClose);
          time = ReadValues[1].split(":");
          if(time[0].charAt(0) == 0){
              closeh = time[0].charAt(1)
          }else{
              closeh = time[0]
          }
          if(time[1].charAt(0) == 0){
              closem = time[1].charAt(1)
          }else{
              closem = time[1]
          }
      
          (function () {if (openschedule) {clearSchedule(openschedule); openschedule = null;}})();
          
          openschedule = schedule(openm + " " + openh + " * * " + Crondays, async function () {
          setState("shelly.0.SHSW-25#3494547C0118#1.Shutter.Position"/*Position*/, 100);
          setState("shelly.0.SHSW-25#3494547BF020#1.Shutter.Position"/*Position*/, 100);
          });
      
          (function () {if (closeschedule) {clearSchedule(closeschedule); closeschedule = null;}})();
          
          closeschedule = schedule(closem + " " + closeh + " * * " + Crondays, async function () {
          setState("shelly.0.SHSW-25#3494547C0118#1.Shutter.Position"/*Position*/, 0);
          setState("shelly.0.SHSW-25#3494547BF020#1.Shutter.Position"/*Position*/, 0);
          });
      
      });
      

      Nun habe ich das Problem, dass die Schedules funktionieren wenn ich die Zeiten z.B. auf in 5 Minuten stelle. Das auch zuverlässig. Wenn aber der nächste Schedule am folgenden Morgen laufen müsste, tut er es meistens nicht. Manchmal, aber nicht immer. Ich habe dieses Script für 2 Räume laufen, bei einem hat es dann mal funktioniert, beim anderen nicht. Ich frage mich woran das liegen könnte. Habt ihr eine Idee?

      Darüber hinaus wäre ich an Verbesserungsvorschlägen interessiert wie man das Ganze noch besser lösen könnte, oder, falls der Weg schon gar nicht so schlecht sein sollte, wie ich das Script optimiert bekomme.

      Vielen Dank für Eure Hilfe! Peter

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

        @messenjah
        Weshalb zeigst du nicht das Blockly?
        Es werden bei Skriptstart keine Zeitpläne erstellt.

        M 1 Reply Last reply Reply Quote 0
        • M
          Messenjah @paul53 last edited by Messenjah

          @paul53
          Weil ich das in JavaScript direkt geschrieben habe und kein Blockly dazu habe. Die Auslesefunktion der Objektinfos muss ich ja auch in JavaScript schreiben. Hab zumindest das nicht mit Blockly hinbekommen. Da fand ich es einfacher gleich alles in JS zu schreiben.

          Ja, ich weiß, dass bei Scriptstart kein Schedule erstellt wird. Das Script soll ja im Prinzip auch durchlaufen und den Schedule basierend auf der Eingabe dann anpassen. Das heißt, dass ich natürlich, nach Start des Scripts, noch einmal eine Änderung in der Gui mache, damit der Schedule dann auch erstellt wird.

          paul53 2 Replies Last reply Reply Quote 0
          • paul53
            paul53 @Messenjah last edited by paul53

            @messenjah sagte: gleich alles in JS zu schreiben.

            Einige Teile sehen aber sehr nach Blockly aus (Zeile 1, Trigger, Zeitplan stoppen, ...).

            Du hast eigene Datenpunkte unter "shelly.0" erstellt? Das sollte man nicht machen, da die Datenpunkte vom Shelly-Adapter verwaltet werden.

            @messenjah sagte in Flexibler Schedule für Rolladensteuerung über Jarvis steuern:

            Die Auslesefunktion der Objektinfos muss ich ja auch in JavaScript schreiben.

            Es wird zwar [desc, value] zurück gegeben, desc aber nirgends verwendet.

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

              @messenjah sagte: alles in JS

              Vorschlag für ein lesbares Javascript mit eigenen Datenpunkten unter "0_userdata.0":

              const path = '0_userdata.0.Office.Blinds_Schedule.';
              const idsWd = [
                  path + 'Day_Su',
                  path + 'Day_Mo',
                  path + 'Day_Tu',
                  path + 'Day_We',
                  path + 'Day_Th',
                  path + 'Day_Fr',
                  path + 'Day_Sa'
              ];
              const idOpen = path + 'Time_Open';
              const idClose = path + 'Time_Close';
              const idBlind1 = 'shelly.0.SHSW-25#3494547C0118#1.Shutter.Position';
              const idBlind2 = 'shelly.0.SHSW-25#3494547BF020#1.Shutter.Position';
              
              var timeOpen = getState(idOpen).val;
              var timeClose = getState(idClose).val;
              var schedOpen = null;
              var schedClose = null;
              
              function getCron(time) {
                  time = time.split(':');
                  let wds = [];
                  for(let i = 0; i < idsWd.length; i++) {
                      if(getState(idsWd[i]).val) wds.push(i);
                  }
                  if(wds.length) return time[1] + ' ' + time[0] + ' * * ' + wds.join(',');
                  return ''; // kein Wochentag ausgewählt
              }
              
              function setOpen(time) {
                  if(schedOpen) {clearSchedule(schedOpen); schedOpen = null;}
                  let cron = getCron(time);
                  if(cron) {
                      schedOpen = schedule(cron, function() {
                          setState(idBlind1, 100);
                          setState(idBlind2, 100);
                      });
                  }
              }
              
              function setClose(time) {
                  if(schedClose) {clearSchedule(schedClose); schedClose = null;}
                  let cron = getCron(time);
                  if(cron) {
                      schedClose = schedule(cron, function() {
                          setState(idBlind1, 0);
                          setState(idBlind2, 0);
                      });
                  }
              }
              
              // Skriptstart
              setOpen(timeOpen);
              setClose(timeClose);
              
              // Trigger Open
              on(idOpen, function(dp) {
                  timeOpen = dp.state.val;
                  setOpen(timeOpen);
              });
              
              // TriggerClose
              on(idClose, function(dp) {
                  timeClose = dp.state.val;
                  setClose(timeClose);
              });
              
              // Trigger Wochentage
              on(idsWd, function () {
                  setOpen(timeOpen);
                  setClose(timeClose);
              });
              

              EDIT: Zeile 25 korrigiert.

              M 1 Reply Last reply Reply Quote 0
              • M
                Messenjah @paul53 last edited by

                @paul53
                Erstmal: Respekt! Vielen Dank, dass du dir die Zeit genommen hast dir das so tief anzuschauen.

                @paul53 sagte: Einige Teile sehen aber sehr nach Blockly aus (Zeile 1, Trigger, Zeitplan stoppen, ...).
                Zugegeben, ich bin hier autodidaktisch unterwegs und habe mir die Syntax zu großen Teilen aus den Blockly Bausteinen zusammenkopiert.

                @paul53 sagte: Du hast eigene Datenpunkte unter "shelly.0" erstellt? Das sollte man nicht machen, da die Datenpunkte vom Shelly-Adapter verwaltet werden.
                Ok, das habe ich dann in der Zwischenzeit auch an anderer Stelle hier im Forum schon gelesen. Falls ich also eigene Datenpunkte bräuchte, sollte ich dir ausschließlich unter userdata anlegen, richtig?

                @paul53 sagte: Es wird zwar [desc, value] zurück gegeben, desc aber nirgends verwendet.
                Ach stimmt ja eigentlich, ein Relikt weil ich zwischendurch eine andere Idee hatte das Ziel zu erreichen....

                @paul53 sagte: Vorschlag für ein lesbares Javascript mit eigenen Datenpunkten unter "0_userdata.0":
                Ich schau es mir mal an. Sieht auf jedenfall sehr vielversprechend aus.

                Warum meine Variante aber über Nacht manchmal einfach nichts mehr gemacht hat (ich weiß natürlich nicht ob dann nach zwei Tagen er wieder was gemacht hätte, weil ich das Script spätestens ja am nächsten Tag wieder angepasst hatte) ist nicht so eindeutig erkennbar, oder? Heute morgen z.B. hat es tatsächlich in beiden Räumen geklappt. Hatte aber nach 0:00 Uhr noch daran rumgedoktort. Wird übernacht irgend ein Dienst neugestartet der die Schedules beeinträchtigen könnte? Dein Script basiert ja auch auf der schedule() Funktion, aber wie gesagt muss ich mir das gleich noch genau anschauen.

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

                  @messenjah sagte: Falls ich also eigene Datenpunkte bräuchte, sollte ich dir ausschließlich unter userdata anlegen, richtig?

                  Ja, unter "0_userdata.0".

                  @messenjah sagte in Flexibler Schedule für Rolladensteuerung über Jarvis steuern:

                  Warum meine Variante aber über Nacht manchmal einfach nichts mehr gemacht hat (ich weiß natürlich nicht ob dann nach zwei Tagen er wieder was gemacht hätte, weil ich das Script spätestens ja am nächsten Tag wieder angepasst hatte) ist nicht so eindeutig erkennbar, oder?

                  Nein, man verliert aber leicht die Übersicht.

                  M 1 Reply Last reply Reply Quote 0
                  • M
                    Messenjah @paul53 last edited by Messenjah

                    @paul53
                    Hm, also ich habe versucht das Script zum Laufen zu bekommen, aber mir scheint, als würde die getCron function nicht richtig zu funktionieren. Obwohl die Wochentage true sind, zählt er wds in der for Schleife nicht hoch.

                    Hat das bei dir funktioniert?
                    Edit: Ach, habs gefunden. wds.push[] muss wds.push() sein, dann funktioniert es. Cool!

                    Dann noch die Frage, du baust ja den Wert für die Tage (die du dann schedule() übergibst) auf indem du sie einfach mit Komma separierst. Akzeptiert die scheduler Funktion diese Syntax? Ich habe im Prinzip versucht den Wert für die Tage so hinzubekommen wie er in Blockly auch über den Wizard erzeugt wird. Und da wäre z.b., wenn ich So,Mo, Di, Do und Fr angehakt hätte, 0-2,4,5 bei rausgekommen. Wenn ich aber 0,1,2,4,5 auch hätte schreiben können, dann wäre mein Script von vornherein auch übersichtlicher gewesen.

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

                      @messenjah sagte: wds.push[] muss wds.push() sein

                      Sorry, habe mich vertippt (nicht getestet).

                      @messenjah sagte in Flexibler Schedule für Rolladensteuerung über Jarvis steuern:

                      Akzeptiert die scheduler Funktion diese Syntax?

                      Ja.

                      M 1 Reply Last reply Reply Quote 0
                      • M
                        Messenjah @paul53 last edited by

                        @paul53 Danke dir für deine Unterstütztung! Ich werde jetzt deinen Vorschlag so weiterverwenden. 🙂

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

                        Support us

                        ioBroker
                        Community Adapters
                        Donate

                        484
                        Online

                        31.8k
                        Users

                        80.0k
                        Topics

                        1.3m
                        Posts

                        2
                        10
                        375
                        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