Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. Zustandsautomat (State Machine) Skript

    NEWS

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    Zustandsautomat (State Machine) Skript

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

      Hallo,

      mit dem clearSchedule von BlueFox habe ich ein Zustandsautomat Skript implementiert. Dieses Skript ändert um gewiesen Zeitpunkten ein Zustands-variable. Ich Benutze die, um aktionen wie Rollanden, Heizung, Wecker, etc zu steuern. Die Zeitpunkte sind in eigene Variablen definiert, die ich später via VIS konfigurierbar machen will

      Es ist ein erstes Version und da meine Erfahrung mit Javascript außerhalb von iobroker null ist wird es vermutlich noch Anpassungen brauchen aber vielleicht hilft es schon jemand.

      Update: version 1.1

      • State times werden jetzt in einem Baumstruktur definiert.
      // iobroker state machine v 1.1
      // 
      // Features:
      // - update state variable at times defined in extra variables
      // - update a preview state variable (usefull to adjust heating in advance)
      // - use diferent times for free days and work days
      //   - this requires another script
      //
      // Changelog
      // 1.0 Initial version 
      // 1.1 Store variables in tree structure (easier to display in iobroker.admin) 
      //
      
      //Id of the javascript adaptor instance where variables should be created/read
      var JAVASCRIPT_INSTANCE_ID = "javascript.0";
      //Variable name where state is stored to
      var STATE_VAR_NAME = "homeState";
      //Variable name where state preview is stored to
      var STATE_VAR_PREVIEW_NAME = "homeStatePreview";
      //Number of hours the the state preview changes before state does
      var PREVIEW_DELTA_HOURS = 1;
      //Bool variable where external script writes if today is a freeday
      var IS_FREEDAY_TODAY_VARNAME="isFreeDay.today";
      //Bool variable where external script writes if tomorrow is a freeday
      var IS_FREEDAY_TOMORROW_VARNAME="isFreeDay.tomorrow";
      //Bool variable where external script writes if yesterday was a freeday
      var WAS_FREEDAY_YESTERDAY_VARNAME="isFreeDay.yesterday";
      //Local cache of state information
      var allStateChanges = {};
      
      //************************************************************
      //                       STATE DEFINITIONS
      //************************************************************
      
      //Define work states
      addState("sleeping",        0 /*stateNumber*/, false /*isFreeday*/, "22:00:00" /*initValue*/);
      addState("awakeBeforeWork", 1 /*stateNumber*/, false /*isFreeday*/, "07:00:00" /*initValue*/);
      addState("empty",           2 /*stateNumber*/, false /*isFreeday*/, "09:00:00" /*initValue*/);
      addState("awake",           3 /*stateNumber*/, false /*isFreeday*/, "18:30:00" /*initValue*/);
      
      //Define freeday states
      addState("sleeping",        0 /*stateNumber*/, true  /*isFreeday*/, "23:30:00" /*initValue*/);
      addState("awake",           3 /*stateNumber*/, true  /*isFreeday*/, "09:00:00" /*initValue*/);
      
      //************************************************************
      //                       IMPLEMENTATION
      //************************************************************
      
      function addState(stateName, stateNumber, isFreeday, initValue){
      
          //Define variable name to store the timer value
          var stateFullName = JAVASCRIPT_INSTANCE_ID+".stateTime." + ((isFreeday)?"freeDay":"work") + "." + stateName;
      
          //When we use it as key, we need to replace . with _
          var stateFullNameFlat = stateFullName.replace(/\./g,"_");
      
          //common object for state
          var common = {"role": "homeStates",
                        "type": "string",
                        "desc": "Time to change state to "+stateName+"("+initValue+")."};
      
          //Create variable
          createState(stateFullName, initValue, false, common);
      
          //Function used to (re-)schedule the state changes.
          var sch;
          var schPreview;
          function registerState(obj){
              //Delete old schedules (if any)
              if (sch) clearSchedule(sch);
              if (schPreview) clearSchedule(schPreview);
      
              //get current date
              var schDateObj = obj ? obj.newState : getState(stateFullName);
              var schDateStr = schDateObj ? schDateObj.val : initValue /*first time*/;
              var schDate = addTime(schDateStr);
      
              log("Scheduling state change(number="+stateNumber+", freeDay="+isFreeday+") at "+schDate);
      
              //Remember this state
              allStateChanges[stateFullNameFlat] = {
                  dateStr: schDateStr,
                  stateNumber: stateNumber,
                  isFreeday: isFreeday
              };
      
              //Schedule for state changes
              sch = schedule({hour:   schDate.getHours(),
                              minute: schDate.getMinutes(),
                              second: schDate.getSeconds()},cb(function(){
                  if (isTodayFreeDay() === isFreeday) {
                      log(STATE_VAR_NAME+" CHANGE: "+stateNumber);
                      setState(STATE_VAR_NAME, stateNumber);
                  }
              }));
      
              //One hour before we want to update a previewState variable
              schDate.setHours(schDate.getHours()-PREVIEW_DELTA_HOURS);
      
              log("Scheduling statePreview change("+stateNumber+") at "+schDate);
      
              //Schedule for preview state changes
              schPreview = schedule({hour:   schDate.getHours(),
                                     minute: schDate.getMinutes(),
                                     second: schDate.getSeconds()},cb(function(){
                  if (isTodayFreeDay() === isFreeday) {
                      log(STATE_VAR_PREVIEW_NAME+" CHANGE: "+stateNumber);
                      setState(STATE_VAR_PREVIEW_NAME, stateNumber);
                  }
              }));
      
              //If the state change variable was updated, update the current and preview states
              if (obj) {
                  //This is an update
                  updateState();
              }
      
          }
      
          //Register with current timer
          registerState();
      
          //Register again if the timer changes
          on(stateFullName, cb(registerState));
          log("Subscribed to "+stateFullName);
      }
      
      function updateState(){
          //current state
          var currentDate = new Date();
          var stateNumber = getCurrentState(currentDate);
          setState(STATE_VAR_NAME, stateNumber);
          log(STATE_VAR_NAME + " set to " + stateNumber);
      
          //preview state
          var previewDate = currentDate;
          previewDate.setHours(previewDate.getHours() + PREVIEW_DELTA_HOURS /*One hour in the future*/);
          stateNumber = getCurrentState(previewDate);
          setState(STATE_VAR_PREVIEW_NAME, stateNumber);
          log(STATE_VAR_PREVIEW_NAME + " set to " + stateNumber);
      }
      
      function getCurrentState(currentDate) {
          var isTodayFreeDay_l = isTodayFreeDay();
          var wasYesterdayFreeDay_l = wasYesterdayFreeDay();
          var isTomorrowFreeDay_l = isTomorrowFreeDay();
      
          //log("getCurrenState for "+JSON.stringify(currentDate.getHours()));
      
          var stateNumber2set;
          var largestDate;
          function checkCandidate(candidateDate, stateNumber){
              //log("Checking "+JSON.stringify(candidateDate));
              if (candidateDate <= currentDate){
                  //This is a valid state candidate
                  if ((largestDate === undefined) || (candidateDate > largestDate)){
                      //Better candidate
                      stateNumber2set = stateNumber;
                      largestDate     = new Date(candidateDate);
                  }
              }
          }
      
          var candidateDate;
          for (var stateChangeName in allStateChanges) {
              if (allStateChanges.hasOwnProperty(stateChangeName)) {
                  //log("Element: "+JSON.stringify(allStateChanges[stateChangeName]));
                  //Check elements
                  candidateDate = addTime(allStateChanges[stateChangeName].dateStr);
      
                  //Check today
                  if (allStateChanges[stateChangeName].isFreeday === isTodayFreeDay_l) {                
                      checkCandidate(candidateDate, allStateChanges[stateChangeName].stateNumber);
                  }
      
                  //Check yesterday
                  if (allStateChanges[stateChangeName].isFreeday === wasYesterdayFreeDay_l) {
                      candidateDate_yesterday = candidateDate;
                      candidateDate_yesterday.setDate(candidateDate_yesterday.getDate() - 1);
                      checkCandidate(candidateDate_yesterday, allStateChanges[stateChangeName].stateNumber);
                  }
      
                  //Check tomorrow
                  if (allStateChanges[stateChangeName].isFreeday === isTomorrowFreeDay_l) {
                      candidateDate_tomorrow = candidateDate;
                      candidateDate_tomorrow.setDate(candidateDate_tomorrow.getDate() + 1);
                      checkCandidate(candidateDate_tomorrow, allStateChanges[stateChangeName].stateNumber);
                  }
              }
          }
          return stateNumber2set;
      }
      
      function isTodayFreeDay(){
          createState(IS_FREEDAY_TODAY_VARNAME,true);
          return getState(IS_FREEDAY_TODAY_VARNAME).val;
      }
      
      function wasYesterdayFreeDay(){
          createState(WAS_FREEDAY_YESTERDAY_VARNAME,true);
          return getState(WAS_FREEDAY_YESTERDAY_VARNAME).val;
      }
      
      function isTomorrowFreeDay(){
          createState(IS_FREEDAY_TOMORROW_VARNAME,true);
          return getState(IS_FREEDAY_TOMORROW_VARNAME).val;
      }
      
      //Create home state (in case it does not exists)
      createState(STATE_VAR_NAME);
      createState(STATE_VAR_PREVIEW_NAME);
      
      //Create variable that groups the state change times
      createState(JAVASCRIPT_INSTANCE_ID+".stateTime",        null,false,{"role": "homeStates","desc":"Time to change variables"});
      createState(JAVASCRIPT_INSTANCE_ID+".stateTime.freeDay",null,false,{"role": "homeStates","desc":"Time to change variables for free days"});
      createState(JAVASCRIPT_INSTANCE_ID+".stateTime.work",   null,false,{"role": "homeStates","desc":"Time to change variables for work days"});
      
      //Set current state
      updateState();
      
      

      827_statetimes.png

      1 Reply Last reply Reply Quote 0
      • V
        vegetto last edited by

        Update: version 1.1

        • State times werden jetzt in einem Baumstruktur definiert.

        ![](</s><URL url=)<link_text text="http://forum.iobroker.net/download/file ... 50bb7c0f49">http://forum.iobroker.net/download/file.php?mode=view&id=2455&sid=610e0fb156af1e900f038c50bb7c0f49</link_text>" />

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

        Support us

        ioBroker
        Community Adapters
        Donate

        741
        Online

        31.7k
        Users

        79.7k
        Topics

        1.3m
        Posts

        1
        2
        1129
        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