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. Zustandsautomat (State Machine) Skript

NEWS

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

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.2k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.1k

Zustandsautomat (State Machine) Skript

Geplant Angeheftet Gesperrt Verschoben Skripten / Logik
2 Beiträge 1 Kommentatoren 1.2k Aufrufe
  • Ä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.
  • V Offline
    V Offline
    vegetto
    schrieb am zuletzt editiert von
    #1

    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 Antwort Letzte Antwort
    0
    • V Offline
      V Offline
      vegetto
      schrieb am zuletzt editiert von
      #2

      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 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

      999

      Online

      32.4k

      Benutzer

      81.5k

      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