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. Cloud Dienste
  4. [Problem] Fibaro Roller Shutter mit Alexa nach % steuern

NEWS

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    11
    1
    524

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    24
    1
    1.7k

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

[Problem] Fibaro Roller Shutter mit Alexa nach % steuern

Geplant Angeheftet Gesperrt Verschoben Cloud Dienste
34 Beiträge 11 Kommentatoren 4.5k Aufrufe 1 Watching
  • Ä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.
  • H Offline
    H Offline
    heromic
    schrieb am zuletzt editiert von
    #3

    Vielen Dank für die Antwort und ausführliche Erklärung.

    Das ist zwar nicht das was ich hören wollte :(

    Aber dann kann ich wenigstens aufhören irgendwelche Einstellungen zu verändern und mich mit meinen anderen Problemen beschäftigen.

    Falls jemand hierfür eine Lösung per Skript erarbeitet hat, würde ich mich über eine Info freuen.

    Grüße

    Heromic

    1 Antwort Letzte Antwort
    0
    • AlCalzoneA Offline
      AlCalzoneA Offline
      AlCalzone
      Developer
      schrieb am zuletzt editiert von
      #4

      @heromic:

      Falls jemand hierfür eine Lösung per Skript erarbeitet hat, würde ich mich über eine Info freuen. `
      Wie gesagt, such mal nach dem Virtual Devices-Skript. Eventuell ist es damit möglich, mit einer recht einfachen Definition deine States "umzubiegen".

      Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

      1 Antwort Letzte Antwort
      0
      • eumatsE Offline
        eumatsE Offline
        eumats
        schrieb am zuletzt editiert von Jey Cee
        #5

        Moin. Ich haben den Fibaro Roller Shutter 2 im Einsatz und nutze ihn per Homekit (yahka Adapter) Alexa und manuell über die Tasten.

        Das Ganze habe ich mit Hilfe des Virtual Devices-Skript umgesetzt. Bei mir ist 0= Rollladen geschlossen und 100=Rollladen geöffnet.

        Das Skript unter common legt 4 Datenpunkte unter javascript.0.virtualDevice.Rolllaeden.EsszimmerOsten (Pfad kann konfiguriert werden) an.

        1. AlexaLevel -> Rollladen in cloud Adapter einbinden und mit Alexa steuern. Funktion: hoch, runter und angesagt %-Zahl

        2. LevelRollo -> Abbild (binding) mit Level_1 des zwave Aktors

        3. PowerRollo -> Abbild (binding) mit Power_1 des zwave Aktors

        4. TargetLevel -> Hier wird der Zielwert, auf den der Rollladen fahren soll, reingeschrieben.

        Hinweis: Diese Lösung ist recht yahka spezifisch. Sollte yahka nicht genutzt werden muss das Skript unter common sicher angepasst werden. Ggf. kann ich hier unterstützen.

        Details zu 2. und 3.:

        Zur korrekten Darstellung von öffnen und schließen in yahka ist es wichtig, dass ein Datenpunkt den Zielwert (TargetLevel, z.B. 70%) und ein Datenpunkt den IST-Wert anzeigt (TargetLevel, z.B. 0%).

        Daher die beiden Datenpunkte.

        Details zu 4.:

        Für die korrekte Anzeige des %-Werte in yahka bei manueller Betätigung über den Taster direkt am Fibaro Aktor werte ich PowerRollo aus. Also: Wenn der Rollladen still steht (PowerRollo < 1 für 5000ms) dann setze den Targetwert auf den IST-Wert.

        Da ich vielen Funktionen unter global ausgelagert habe, habe ich ich der Einfachheit halber alles in ein Skript zusammen kopiert. Ich hoffe mir ist da kein Fehler unterlaufen.

        Eigentlich müssen nur die Variablen LevelDevice und PowerDevice an den eigene Aktor angepasst werden, Skript Starten, erzeugte Datenpunkte in die Adapter einbinden, fertig.

        Ich hoffe ich habe nix vergessen. Ich habe das mal schnell auf der Arbeit zusammengeschrieben.

        Unter global einfügen und starten:

        /*VirtualDevice v0.3
        // http://forum.iobroker.net/viewtopic.php?f=21&t=8192&hilit=virtuelle+Geräte
        var AdapterPfadVirtuelleGeraete = 'javascript.',
            virtualDevicePfad = 'virtualDevice.';
        Structure of config:
        {
           name: 'name', //name of device
           namespace: '', //create device within this namespace (device ID will be namespace.name)
           common: {}, //(optional)
           native: {}, //(optional)
           copy: objectId, //(optional) ID of device or channel to copy common and native from
           onCreate: function(device, callback) {} //called once on device creation
           states: {
               'stateA': { //State Id will be namespace.name.stateA
                   common: {}, //(optional)
                   native: {}, //(optional)
                   copy: stateId,
                   read: {
                       //(optional) states which should write to "stateA"
                       'stateId1': {
                           trigger: {ack: true, change: 'any'} //(optional) see https://github.com/ioBroker/ioBroker.javascript#on---subscribe-on-changes-or-updates-of-some-state
                           convert: function(val) {}, //(optional) functions should return converted value 
                           before: function(device, value, callback) {}, //(optional) called before writing new state. has to call callback or new value will not be written 
                           delay: 0, //(optional) delay in ms before new value gets written
                           after: function(device, value) {}, //(optional) called after new value has been written
                           validFor: //(optional) ms, to ignore old data which did not change for a long time.  
                       },
                       ...
                   },
                   readLogic: 'last' || 'max' || 'min' || 'average', //(optional) default: last (only last implemented)
                   write: {
                       //(optional) states which "stateA" should write to 
                       'stateId1': {
                           convert: function(val) {}, //(optional) functions should return converted value 
                           before: function(device, value, callback) {}, //(optional) called before writing new state. has to call callback or new value will not be written 
                           delay: 0, //(optional) delay in ms before new value gets written
                           after: function(device, value) {}, //(optional) called after new value has been written
                       },     
                       'stateId3': {
                           convert: function(val) {}, //(optional) functions should return converted value 
                           before: function(device, value, callback) {}, //(optional) called before writing new state. has to call callback or new value will not be written 
                           delay: 0, //(optional) delay in ms before new value gets written
                           after: function(device, value) {}, //(optional) called after new value has been written
                       },
                       ...
                   },
               },
               ...
           }
        }
        */
        //generic virtual device        
        function VirtualDevice(config) {
           //sanity check
           if (typeof config !== 'object' || typeof config.namespace !== 'string' || typeof config.name !== 'string' || typeof config.states !== 'object') {
               log('sanity check failed, no device created', 'warn');
               return;
           }
            this.config = config;
           this.namespace = virtualDevicePfad + config.namespace + '.' + config.name;
           this.name = config.name;
            //create virtual device
           //log('creating virtual device ' + this.namespace)
           this.createDevice(function () {
               this.createStates(function () {
                   //log('created virtual device ' + this.namespace)
               }.bind(this));
           }.bind(this));
        }
        VirtualDevice.prototype.createDevice = function (callback) {
           //log('creating object for device ' + this.namespace, 'debug');
           //create device object
           var obj = this.config.copy ? getObject(this.config.copy) : {common: {}, native: {}};
           delete obj.common.custom;
           if (typeof this.config.common === 'object') {
               obj.common = Object.assign(obj.common, this.config.common);
           }
           if (typeof this.config.native === 'object') {
               obj.native = Object.assign(obj.native, this.config.native);
           }
           extendObject(AdapterPfadVirtuelleGeraete + instance + '.' + this.namespace, {
               type: "device",
               common: obj.common,
               native: obj.native
           }, function (err) {
               if (err) {
                   log('could not create virtual device: ' + this.namespace, 'warn');
                   return;
               }
               log('created object for device ' + this.namespace, 'debug');
               if (typeof this.config.onCreate === 'function') {
                   this.config.onCreate(this, callback);
               } else {
                   callback();
               }
           }.bind(this));
        }
        VirtualDevice.prototype.createStates = function (callback) {
           "use strict";
           log('creating states for device ' + this.namespace, 'debug');
           var stateIds = Object.keys(this.config.states);
           log('creating states ' + JSON.stringify(stateIds), 'debug');
           var countCreated = 0;
           for (var i = 0; i < stateIds.length; i++) {
               let stateId = stateIds[i];
               this.normalizeState(stateId);
               var id = this.namespace + '.' + stateId;
               log('creating state ' + id, 'debug');
               var obj = this.config.states[stateId].copy ? getObject(this.config.states[stateId].copy) : {
                   common: {},
                   native: {}
               };
               delete obj.common.custom;
               if (typeof this.config.states[stateId].common === 'object') {
                   obj.common = Object.assign(obj.common, this.config.states[stateId].common);
               }
               if (typeof this.config.states[stateId].native === 'object') {
                   obj.native = Object.assign(obj.native, this.config.states[stateId].native);
               }
               createState(id, obj.common, obj.native, function (err) {
                   if (err) {
                       log('skipping creation of state ' + id, 'debug');
                   } else {
                       log('created state ' + id, 'debug');
                   }
                   this.connectState(stateId);
                   countCreated++;
                   if (countCreated >= stateIds.length) {
                       log('created ' + countCreated + ' states for device ' + this.namespace, 'debug');
                       callback();
                   }
               }.bind(this));
           }
        }
        VirtualDevice.prototype.normalizeState = function (state) {
           log('normalizing state ' + state, 'debug');
           if (typeof this.config.states[state].read !== 'object') {
               this.config.states[state].read = {};
           }
           if (typeof this.config.states[state].write !== 'object') {
               this.config.states[state].write = {};
           }
            var readIds = Object.keys(this.config.states[state].read);
           for (var i = 0; i < readIds.length; i++) {
               var readId = this.config.states[state].read[readIds[i]];
               if (typeof readId.before !== 'function') {
                   this.config.states[state].read[readIds[i]].before = function (device, value, callback) {
                       callback()
                   };
               }
               if (typeof readId.after !== 'function') {
                   this.config.states[state].read[readIds[i]].after = function (device, value) {
                   };
               }
           }
           var writeIds = Object.keys(this.config.states[state].write);
           for (i = 0; i < writeIds.length; i++) {
               var writeId = this.config.states[state].write[writeIds[i]];
               if (typeof writeId.before !== 'function') {
                   this.config.states[state].write[writeIds[i]].before = function (device, value, callback) {
                       callback()
                   };
               }
               if (typeof writeId.after !== 'function') {
                   this.config.states[state].write[writeIds[i]].after = function (device, value) {
                   };
               }
           }
           log('normalized state ' + state, 'debug');
        }
        VirtualDevice.prototype.connectState = function (state) {
           log('connecting state ' + state, 'debug');
           var id = this.namespace + '.' + state;
            //subscribe to read ids
           var readIds = Object.keys(this.config.states[state].read);
           for (var i = 0; i < readIds.length; i++) {
               if (getState(readIds[i]).notExist === true) { //check if state exists
                   log('cannot connect to not existing state: ' + readIds[i], 'warn');
                   continue;
               }
               var readObj = this.config.states[state].read[readIds[i]];
               var trigger = readObj.trigger || {change: 'any'};
               trigger.ack = true;
               trigger.id = readIds[i];
               this.subRead(trigger, readObj, state);
               log('connected ' + readIds[i] + ' to ' + id, 'debug');
           }
            //subscribe to this state and write to write ids
           var writeIds = Object.keys(this.config.states[state].write);
           var trigger = {id: AdapterPfadVirtuelleGeraete + instance + '.' + this.namespace + '.' + state, change: 'any', ack: false};
           on(trigger, function (obj) {
               "use strict";
               log('detected change of ' + state, 'debug');
               for (var i = 0; i < writeIds.length; i++) {
                   let writeObj = this.config.states[state].write[writeIds[i]];
                   let val = this.convertValue(obj.state.val, writeObj.convert);
                   let writeId = writeIds[i];
                   log('executing function before for ' + writeId, 'debug');
                   writeObj.before(this, val, function (newVal, newDelay) {
                       if (newVal !== undefined && newVal !== null) val = newVal;
                       var delay = writeObj.delay;
                       if (newDelay !== undefined && newDelay !== null) delay = newDelay;
                       log(newVal + 'writing value ' + val + ' to ' + writeId + ' with delay ' + delay, 'debug');
                       setStateDelayed(writeId, val, false, delay || 0, true, function () {
                           log('executing function after for ' + writeId, 'debug');
                           writeObj.after(this, val);
                       }.bind(this));
                   }.bind(this));
               }
           }.bind(this));
           log('connected ' + state + ' to ' + JSON.stringify(writeIds), 'debug');
        }
        VirtualDevice.prototype.subRead = function (trigger, readObj, state) {
           var func = function (obj) {
               var val = this.convertValue(obj.state.val, readObj.convert);
               //@todo aggregations
                log('executing function before for ' + trigger.id, 'debug');
               readObj.before(this, val, function (newVal, newDelay) {
                   if (newVal !== undefined && newVal !== null) val = newVal;
                   if (newDelay !== undefined && newDelay !== null) writeObj.delay = newDelay;
                   log('reading value ' + val + ' to ' + this.namespace + '.' + state, 'debug');
                   setStateDelayed(this.namespace + '.' + state, val, true, readObj.delay || 0, true, function () {
                       log('executing function after for ' + trigger.id, 'debug');
                       readObj.after(this, val);
                   }.bind(this));
               }.bind(this));
           }.bind(this);
           func({state: getState(trigger.id)});
           on(trigger, func);
        }
        VirtualDevice.prototype.convertValue = function (val, func) {
           if (typeof func !== 'function') {
               return val;
           }
           return func(val);
        }
        

        Unter commoneinfügen und starten (Es kann ggf. sein, dass das Skript 2x gestartet werden muss, da das Erzeugen der Datenpunkte und das zugehörige binding "sich nicht finden":

        // Alle Datenpunkte erzeugen, die dieses Gerät benötigt
        var LevelDevice = 'zwave.0.NODE10.SWITCH_MULTILEVEL.Level_1',
            PowerDevice = 'zwave.0.NODE10.SENSOR_MULTILEVEL.Power_1';
        
        var WriteTargetLevelTimeout = 5000, // Timeout für das Schreiben des Levelwerte in den Targetwert bei Fibaro Rollladenaktoren.
            LevelPowerRolloMeldewert = 1; // Kleiner diesen Wert wird der Rollladen als stillstehend erkannt.
         // Der Datenpunkt des Cloudadapters zur Alexa Rollladensteuerung hoch/runter
        var cloudAlexa = 'cloud.0.smart.lastCommand';
        var basisPfad = 'javascript.0.virtualDevice.';
        
        var ersteSubEbene = 'Rolllaeden',
            zweiteSubEbene = 'EsszimmerOsten',
            kompletterPfad = [basisPfad,ersteSubEbene,'.',zweiteSubEbene,'.'].join(''),
            Alexa = 'AlexaLevel',
            LevelRollo = 'LevelRollo',
            TargetLevel = 'TargetLevel';
        var Rollo_Alexa = [kompletterPfad,Alexa].join(''),
            TargetLevel = [kompletterPfad,TargetLevel].join(''),
            LevelRollo = [kompletterPfad,LevelRollo].join(''),
            Schreibverzoegerung;
        
        var Name = 'Rollladen WZ Osten ',
            AlexaTag = Name + 'Alexasteuerung',
            LevelTag = Name + 'Level Aktor',
            PowerTag = Name + 'Power Aktor',
            TargetTag = Name + 'Target-Level für Homekit';
        
        createState(Rollo_Alexa, {
            type: 'number',
            name: AlexaTag,
            min: 0,
            max: 100,
            def: 0,
            read: true,
            write: true
        });
        createState(TargetLevel, {
            type: 'number',
            name: TargetTag,
            min: 0,
            max: 100,
            def: 0,
        });
        // Hilfsfunktionen...
        // Konvertiert die Fibarowerte (0-99) in ein Wert von 0-100
        // Manchmal zeigt Level_1 der Aktoren nach einer manuellen Bedienung nicht 0/99 an, sondern 1 oder 96\. Das wird hier korrigiert
        function convertFibaroAuf (wertFibaroAuf) {
            if (wertFibaroAuf >= 95) {
                return(100);
            } else if (wertFibaroAuf <= 2) {
                return(0);
            } else {
                return(wertFibaroAuf);
            }
        }
        function convertFibaroZu (wertFibaroZU) {
            if (wertFibaroZU == 100) {
                return (99);
            } else {
                return(wertFibaroZU);
            }
        }
        // Umsetzung von hoch und runter mit Alexa
        function steuereRolllaedenAlexa(Rollladen) {
            letztesAlexaKommando = getState(cloudAlexa).val;
            // if Abfrage, um hoch und runter von Alexa zu ermöglichen
            if (letztesAlexaKommando == '--25') {
                // fahre Rolladen runter
                return 'runter';
            } else if (letztesAlexaKommando == '+25') {
                // fahre Rolladen hoch
                return 'hoch';
            } else {
                // Mache das, was Alexa in den Datenpunkt schreibt
                return 'nativ';
            }
        }
        // Verarbeitung der virtuellen Geräte für die Fibaro Aktoren.
        // Level_1 und Power_1
        new VirtualDevice({
            // z.B. 'Rollaeden' für javascript.0.virtualDevice.Rollaeden... oder 'Rolllaeden.bla' javascript.0.virtualDevice.Rollaeden.bla...
            namespace: ersteSubEbene,
            name: zweiteSubEbene, //das Gerät wird unter javascript.0.virtualDevice.namespace.name erstellt
            states: {
                //welche States sollen erstellt werden?
                'LevelRollo': {
                    //State Konfiguration
                    common: {type: 'number', def: 0, min: 0, max: 100, read: true, write: true, name: LevelTag},
                    read: {
                        //von welchen States sollen Werte eingelesen werden?
                        [LevelDevice]: {
                            convert: function (val) { //wert soll konvertiert werden
                                // Konvertiere die Fibarowerte zu 0-100
                                var wert = convertFibaroAuf(val);
                                //console.log('### LevelRollo: ' + wert);
                                return wert;
                            },
                        },
                    },
                    write: {
                        //in welche States sollen Werte geschrieben werden?
                        [LevelDevice]: {
                            convert: function (val) { //wert soll konvertiert werden
                                // Konvertiere die Fibarowerte zu 0-100
                                var wert =  convertFibaroZu(val);
                                return wert;
                            },
                        },
                    }
                },
                'PowerRollo': {
                        //State Konfiguration
                        common: {type: 'number', def: 0, min: 0, max: 300, read: true, write: false, name: PowerTag},
                        read: {
                            //von welchen States sollen Werte eingelesen werden?
                            [PowerDevice]: {
                                trigger: {ack: true, change: 'ne'},
                                // Falls der Rolladen manuell bedient wurde, müssen wir nun alles für eine korrekte Anzeige in Homekit bereitstelen
                                after: function(device, value) {
                                    // Mache etwas, wenn der Rollladen still steht, also der Verbrauch kleiner LevelPowerRolloMeldewert ist
                                    if (value < LevelPowerRolloMeldewert) {
                                        var level = getState(LevelRollo).val;
                                        var levelAck = getState(LevelRollo).ack;
                                        var TargetLevelAktuell =  getState(TargetLevel).val;
        
                                        if (!levelAck) {
                                            console.log('### Level NICHT ACK: ' + level + ', levelAck: ' + levelAck);
                                        }
        
                                        // Alten Timer, falls vorhanden, löschen
                                        (function () {if (Schreibverzoegerung) {clearTimeout(Schreibverzoegerung); Schreibverzoegerung = null;}})();
        
                                        // Verzögerung beim Schreiben, da Level_1 machmal etwas länger zum Aktualisieren des Zielwertes braucht.
                                        //console.log('### Level vor TIMEOUT: ' + level + ', levelAck: ' + levelAck);
                                        //console.log('### TargetLevelAktuell vor TIMEOUT: ' + TargetLevelAktuell);
                                        Schreibverzoegerung = setTimeout(function () {
                                            level = getState(LevelRollo).val;
                                            levelAck = getState(LevelRollo).ack;
                                            TargetLevelAktuell =  getState(TargetLevel).val;
        
                                            //console.log('### Level nach TIMEOUT: ' + level + '#, levelAck: ' + levelAck);
                                            //console.log('### TargetLevelAktuell nach TIMEOUT: ' + TargetLevelAktuell);
        
                                            // Wenn Level_1 und Target nicht gleich sind, dann müssen wir etwas machen
                                            if (level != TargetLevelAktuell) {
                                                console.log('Setze Target (aktuell: ' + getState(TargetLevel).val + ') auf: ' + level);   
                                                setState(TargetLevel,level);
                                            } else {
                                                console.log('### TargetLevel muss nicht aktualisiert werden (aktuell: ' + getState(TargetLevel).val + ', Zielwert: ' + level + ').');
                                            }
                                        }, WriteTargetLevelTimeout);
                                    }
                                },
                            },
                        },
                },
            },
        });
        // Verarbeitung des Tagetwertes zur korrekten Bedienung und Anzeige in Homekit
        on({id: TargetLevel, change: "ne"}, function (obj) {
            var value = obj.state.val;
            var oldValue = obj.oldState.val;
            if (value != oldValue) {
                var wert = getState(TargetLevel).val;
        
                setState(LevelRollo, wert);
            }
        });
        // Alexasteuerung
        on({id: Rollo_Alexa, change: "any"}, function (obj) {
            var AlexaAktion = steuereRolllaedenAlexa(Rollo_Alexa),
                wert;
            //console.log('### Alexa: ' + AlexaAktion);
             if (AlexaAktion == 'runter') {
                // fahre Rolladen runter
                wert = 0;
            } else if (AlexaAktion == 'hoch') {
                // fahre Rolladen hoch
                wert = 100;
            } else {
                // fahre Rolladen auf den übergebenen Wert
                wert = value;
            }
        
            // Über den TargetLevel wird dann auch der Frostschutz gesteuert
            setState(TargetLevel,wert);
        });
        

        23.05.2018: Die im Folgenden offenbarten, fehlenden Variablen wurden hinzugefügt.

        O D 2 Antworten Letzte Antwort
        0
        • H Offline
          H Offline
          heromic
          schrieb am zuletzt editiert von
          #6

          Boah

          vielen Dank für die gute und ausführliche Beschreibung.

          Da ich in Skripten noch sehr jungfräulich bin, muss ich darüber mal eine Nacht schlafen um das ganze zu verstehen und auf meine Bedürfnisse anzupassen.

          Zumindestens habe ich jetzt Lösungsansätze auf die ich aufbauen kann.

          1 Antwort Letzte Antwort
          0
          • eumatsE Offline
            eumatsE Offline
            eumats
            schrieb am zuletzt editiert von Dutchman
            #7

            Hier noch mal eine abgespeckte Variante für nicht Apple/homekit Nutzer:

            Er gibt 2 Datenpunkte:

            1. AlexaLevel -> Rollladen in cloud Adapter einbinden und mit Alexa steuern. Funktion: hoch, runter und angesagt %-Zahl

            2. LevelRollo -> Abbild (binding) mit Level_1 des zwave Aktors

            // Alle Datenpunkte erzeugen, die dieses Gerät benötigt
            var LevelDevice = 'zwave.0.NODE10.SWITCH_MULTILEVEL.Level_1',
                PowerDevice = 'zwave.0.NODE10.SENSOR_MULTILEVEL.Power_1';
            // Der Datenpunkt des Cloudadapters zur Alexa Rollladensteuerung hoch/runter
            var cloudAlexa = 'cloud.0.smart.lastCommand';
            
            var ersteSubEbene = 'Rolllaeden',
                zweiteSubEbene = 'EsszimmerOsten',
                kompletterPfad = [basisPfad,ersteSubEbene,'.',zweiteSubEbene,'.'].join(''),
                Alexa = 'AlexaLevel',
                LevelRollo = 'LevelRollo';
            var Rollo_Alexa = [kompletterPfad,Alexa].join(''),
                LevelRollo = [kompletterPfad,LevelRollo].join('');
            
            var Name = 'Rollladen WZ Osten ',
                AlexaTag = Name + 'Alexasteuerung',
                LevelTag = Name + 'Level Aktor';
            
            createState(Rollo_Alexa, {
                type: 'number',
                name: AlexaTag,
                min: 0,
                max: 100,
                def: 0,
                read: true,
                write: true
            });
            // Hilfsfunktionen...
            // Konvertiert die Fibarowerte (0-99) in ein Wert von 0-100
            // Manchmal zeigt Level_1 der Aktoren nach einer manuellen Bedienung nicht 0/99 an, sondern 1 oder 96\. Das wird hier korrigiert
            function convertFibaroAuf (wertFibaroAuf) {
                if (wertFibaroAuf >= 95) {
                    return(100);
                } else if (wertFibaroAuf <= 2) {
                    return(0);
                } else {
                    return(wertFibaroAuf);
                }
            }
            function convertFibaroZu (wertFibaroZU) {
                if (wertFibaroZU == 100) {
                    return (99);
                } else {
                    return(wertFibaroZU);
                }
            }
            // Umsetzung von hoch und runter mit Alexa
            function steuereRolllaedenAlexa(Rollladen) {
                letztesAlexaKommando = getState(cloudAlexa).val;
                // if Abfrage, um hoch und runter von Alexa zu ermöglichen
                if (letztesAlexaKommando == '--25') {
                    // fahre Rolladen runter
                    return 'runter';
                } else if (letztesAlexaKommando == '+25') {
                    // fahre Rolladen hoch
                    return 'hoch';
                } else {
                    // Mache das, was Alexa in den Datenpunkt schreibt
                    return 'nativ';
                }
            }
            // Verarbeitung der virtuellen Geräte für die Fibaro Aktoren.
            // Level_1 und Power_1
            new VirtualDevice({
                // z.B. 'Rollaeden' für javascript.0.virtualDevice.Rollaeden... oder 'Rolllaeden.bla' javascript.0.virtualDevice.Rollaeden.bla...
                namespace: ersteSubEbene,
                name: zweiteSubEbene, //das Gerät wird unter javascript.0.virtualDevice.namespace.name erstellt
                states: {
                    //welche States sollen erstellt werden?
                    'LevelRollo': {
                        //State Konfiguration
                        common: {type: 'number', def: 0, min: 0, max: 100, read: true, write: true, name: LevelTag},
                        read: {
                            //von welchen States sollen Werte eingelesen werden?
                            [LevelDevice]: {
                                convert: function (val) { //wert soll konvertiert werden
                                    // Konvertiere die Fibarowerte zu 0-100
                                    var wert = convertFibaroAuf(val);
                                    //console.log('### LevelRollo: ' + wert);
                                    return wert;
                                },
                            },
                        },
                        write: {
                            //in welche States sollen Werte geschrieben werden?
                            [LevelDevice]: {
                                convert: function (val) { //wert soll konvertiert werden
                                    // Konvertiere die Fibarowerte zu 0-100
                                    var wert =  convertFibaroZu(val);
                                    return wert;
                                },
                            },
                        }
                    },
                },
            });
            >! // Alexasteuerung
            on({id: Rollo_Alexa, change: "any"}, function (obj) {
                var AlexaAktion = steuereRolllaedenAlexa(Rollo_Alexa),
                    wert;
                //console.log('### Alexa: ' + AlexaAktion);
               if (AlexaAktion == 'runter') {
                    // fahre Rolladen runter
                    wert = 0;
                } else if (AlexaAktion == 'hoch') {
                    // fahre Rolladen hoch
                    wert = 100;
                } else {
                    // fahre Rolladen auf den übergebenen Wert
                    wert = value;
                }
            
                setState(LevelRollo,wert);
            });
            
            1 Antwort Letzte Antwort
            0
            • H Offline
              H Offline
              heromic
              schrieb am zuletzt editiert von
              #8

              Hallo,

              wollte das oben gepostete Skript gerade mal bei mir ausprobieren.

              Bekomme folgende Fehlermeldung

              [javascript.0	2018-04-01 14:40:16.935	error	at ContextifyScript.Script.runInContext (vm.js:35:29)
              javascript.0	2018-04-01 14:40:16.934	error	at script.js.common.Test_01-04-2018:10:23
              javascript.0	2018-04-01 14:40:16.934	error	ReferenceError: basisPfad is not defined
              javascript.0	2018-04-01 14:40:16.933	error	^
              javascript.0	2018-04-01 14:40:16.933	error	kompletterPfad = [basisPfad,ersteSubEbene,'.',zweiteSubEbene,'.'].join(''),
              javascript.0	2018-04-01 14:40:16.932	error	script.js.common.Test_01-04-2018: script.js.common.Test_01-04-2018:10]
              

              Ich vermute mal, du hast noch ein weiteres Global Skript aktiv.

              Deshalb kann das Skript nicht den Basis Pfad zuweisen.

              Kannst du mir auf die Sprünge helfen, wie ich das Skript bei mir zum laufen bekomme?

              Vielend Dank

              1 Antwort Letzte Antwort
              0
              • eumatsE Offline
                eumatsE Offline
                eumats
                schrieb am zuletzt editiert von
                #9

                Schreibe mal folgendes in Skript:

                var basisPfad = 'javascript.0.virtualDevice.';
                
                1 Antwort Letzte Antwort
                0
                • H Offline
                  H Offline
                  heromic
                  schrieb am zuletzt editiert von
                  #10

                  Vielen Dank

                  Daumen Hoch !

                  Diese Fehlermeldung ist nun verschwunden und die nächste folgt zugleich …

                  Ich versuche mich aber erstmal ein wenig mit java Script auseinanderzusetzen,

                  damit ich ich das ganze wenigstens ein bisschen nachvollziehen kann

                  1 Antwort Letzte Antwort
                  0
                  • eumatsE Offline
                    eumatsE Offline
                    eumats
                    schrieb am zuletzt editiert von
                    #11

                    @heromic:

                    Vielen Dank

                    Daumen Hoch !

                    Diese Fehlermeldung ist nun verschwunden und die nächste folgt zugleich …

                    Ich versuche mich aber erstmal ein wenig mit java Script auseinanderzusetzen,

                    damit ich ich das ganze wenigstens ein bisschen nachvollziehen kann `

                    Poste mal der Fehlermeldung. Hast Du das Virtual Device Skript wie oben beschrieben in global eingefügt und gestartet?

                    Wie oben geschrieben habe ich das nur mal nebenbei zusammen kopiert. Denn bei mir ist viel in globalen Variablen und zentralen Funktionen ausgelagert. Daher können da sicher Bugs drin sein…

                    1 Antwort Letzte Antwort
                    0
                    • H Offline
                      H Offline
                      heromic
                      schrieb am zuletzt editiert von
                      #12

                      > Hast Du das Virtual Device Skript wie oben beschrieben in global eingefügt und gestartet?

                      Jep, ich denke das war es.

                      Die Fehlermeldung war

                      javascript.0	2018-04-02 17:40:59.526	error	ReferenceError: VirtualDevice is not defined
                      javascript.0	2018-04-02 17:40:59.526	error	^
                      javascript.0	2018-04-02 17:40:59.525	error	new VirtualDevice({
                      

                      Ich habe das Script nochmal gestartet und die Fehlermeldung war verschwunden.

                      Jetzt sehe ich es auch als virtl. device

                      Supi

                      Klasse support

                      Vielen Dank

                      1 Antwort Letzte Antwort
                      0
                      • _ Offline
                        _ Offline
                        _Sven_
                        schrieb am zuletzt editiert von
                        #13

                        Hi zusammen

                        Ich lese seit längerem in diesem Forum mit.

                        Ich habe ebenfalls das problem, dass in meinem Fall Homekit (yahka) "öffnen" einen Wert von 100 übermittelt.

                        Ich habe die beiden Skripts mal importiert und erhalte folgenden Fehler:

                        javascript.0	2018-05-21 00:14:54.669	error	at ContextifyScript.Script.runInContext (vm.js:59:29)
                        javascript.0	2018-05-21 00:14:54.669	error	at script.js.common.v-common:87:1
                        javascript.0	2018-05-21 00:14:54.668	error	at new VirtualDevice (script.js.common.v-common:63:22)
                        javascript.0	2018-05-21 00:14:54.667	error	ReferenceError: virtualDevicePfad is not defined
                        javascript.0	2018-05-21 00:14:54.667	error	^
                        javascript.0	2018-05-21 00:14:54.666	error	this.namespace = virtualDevicePfad + config.namespace + '.' + config.name;
                        javascript.0	2018-05-21 00:14:54.665	error	script.js.common.v-common: script.js.common.v-common:63
                        

                        Kamm mir jemand helfen das Skript für HomeKit anzupassen?

                        Danke und Grüsse

                        Sven

                        1 Antwort Letzte Antwort
                        0
                        • eumatsE Offline
                          eumatsE Offline
                          eumats
                          schrieb am zuletzt editiert von
                          #14

                          Schreib mal folgendes in das Skript in global:

                          var virtualDevicePfad = 'virtualDevice.';
                          
                          1 Antwort Letzte Antwort
                          0
                          • _ Offline
                            _ Offline
                            _Sven_
                            schrieb am zuletzt editiert von Dutchman
                            #15

                            OK

                            hab das in Zeile 61 im global script eingefügt:

                            `/*VirtualDevice v0.3
                            
                            // http://forum.iobroker.net/viewtopic.php?f=21&t=8192&hilit=virtuelle+Geräte
                            
                            Structure of config:
                            {
                                name: 'name', //name of device
                                namespace: '', //create device within this namespace (device ID will be namespace.name)
                                common: {}, //(optional)
                                native: {}, //(optional)
                                copy: objectId, //(optional) ID of device or channel to copy common and native from
                                onCreate: function(device, callback) {} //called once on device creation
                                states: {
                                    'stateA': { //State Id will be namespace.name.stateA
                                        common: {}, //(optional)
                                        native: {}, //(optional)
                                        copy: stateId,
                                        read: {
                                            //(optional) states which should write to "stateA"
                                            'stateId1': {
                                                trigger: {ack: true, change: 'any'} //(optional) see https://github.com/ioBroker/ioBroker.javascript#on---subscribe-on-changes-or-updates-of-some-state
                                                convert: function(val) {}, //(optional) functions should return converted value 
                                                before: function(device, value, callback) {}, //(optional) called before writing new state. has to call callback or new value will not be written 
                                                delay: 0, //(optional) delay in ms before new value gets written
                                                after: function(device, value) {}, //(optional) called after new value has been written
                                                validFor: //(optional) ms, to ignore old data which did not change for a long time.  
                                            },
                                            ...
                                        },
                                        readLogic: 'last' || 'max' || 'min' || 'average', //(optional) default: last (only last implemented)
                                        write: {
                                            //(optional) states which "stateA" should write to 
                                            'stateId1': {
                                                convert: function(val) {}, //(optional) functions should return converted value 
                                                before: function(device, value, callback) {}, //(optional) called before writing new state. has to call callback or new value will not be written 
                                                delay: 0, //(optional) delay in ms before new value gets written
                                                after: function(device, value) {}, //(optional) called after new value has been written
                                            },     
                                            'stateId3': {
                                                convert: function(val) {}, //(optional) functions should return converted value 
                                                before: function(device, value, callback) {}, //(optional) called before writing new state. has to call callback or new value will not be written 
                                                delay: 0, //(optional) delay in ms before new value gets written
                                                after: function(device, value) {}, //(optional) called after new value has been written
                                            },
                                            ...
                                        },
                                    },
                                    ...
                                }
                            }
                            */
                            
                            //generic virtual device   
                            
                            function VirtualDevice(config) {
                                //sanity check
                                if (typeof config !== 'object' || typeof config.namespace !== 'string' || typeof config.name !== 'string' || typeof config.states !== 'object') {
                                    log('sanity check failed, no device created', 'warn');
                                    return;
                                }
                            virtualDevicePfad = 'VirtualDevice.',
                                this.config = config;
                                this.namespace = virtualDevicePfad + config.namespace + '.' + config.name;
                                this.name = config.name;
                            
                                //create virtual device
                                //log('creating virtual device ' + this.namespace)
                                this.createDevice(function () {
                                    this.createStates(function () {
                                        //log('created virtual device ' + this.namespace)
                                    }.bind(this));
                                }.bind(this));
                            }
                            
                            VirtualDevice.prototype.createDevice = function (callback) {
                                //log('creating object for device ' + this.namespace, 'debug');
                                //create device object
                                var obj = this.config.copy ? getObject(this.config.copy) : {common: {}, native: {}};
                                delete obj.common.custom;
                                if (typeof this.config.common === 'object') {
                                    obj.common = Object.assign(obj.common, this.config.common);
                                }
                                if (typeof this.config.native === 'object') {
                                    obj.native = Object.assign(obj.native, this.config.native);
                                }
                                extendObject(AdapterPfadVirtuelleGeraete + instance + '.' + this.namespace, {
                                    type: "device",
                                    common: obj.common,
                                    native: obj.native
                                }, function (err) {
                                    if (err) {
                                        log('could not create virtual device: ' + this.namespace, 'warn');
                                        return;
                                    }
                                    log('created object for device ' + this.namespace, 'debug');
                                    if (typeof this.config.onCreate === 'function') {
                                        this.config.onCreate(this, callback);
                                    } else {
                                        callback();
                                    }
                                }.bind(this));
                            }
                            
                            VirtualDevice.prototype.createStates = function (callback) {
                                "use strict";
                                log('creating states for device ' + this.namespace, 'debug');
                                var stateIds = Object.keys(this.config.states);
                                log('creating states ' + JSON.stringify(stateIds), 'debug');
                                var countCreated = 0;
                                for (var i = 0; i < stateIds.length; i++) {
                                    let stateId = stateIds[i];
                                    this.normalizeState(stateId);
                                    var id = this.namespace + '.' + stateId;
                                    log('creating state ' + id, 'debug');
                                    var obj = this.config.states[stateId].copy ? getObject(this.config.states[stateId].copy) : {
                                        common: {},
                                        native: {}
                                    };
                                    delete obj.common.custom;
                                    if (typeof this.config.states[stateId].common === 'object') {
                                        obj.common = Object.assign(obj.common, this.config.states[stateId].common);
                                    }
                                    if (typeof this.config.states[stateId].native === 'object') {
                                        obj.native = Object.assign(obj.native, this.config.states[stateId].native);
                                    }
                                    createState(id, obj.common, obj.native, function (err) {
                                        if (err) {
                                            log('skipping creation of state ' + id, 'debug');
                                        } else {
                                            log('created state ' + id, 'debug');
                                        }
                                        this.connectState(stateId);
                                        countCreated++;
                                        if (countCreated >= stateIds.length) {
                                            log('created ' + countCreated + ' states for device ' + this.namespace, 'debug');
                                            callback();
                                        }
                                    }.bind(this));
                                }
                            }
                            
                            VirtualDevice.prototype.normalizeState = function (state) {
                                log('normalizing state ' + state, 'debug');
                                if (typeof this.config.states[state].read !== 'object') {
                                    this.config.states[state].read = {};
                                }
                                if (typeof this.config.states[state].write !== 'object') {
                                    this.config.states[state].write = {};
                                }
                            
                                var readIds = Object.keys(this.config.states[state].read);
                                for (var i = 0; i < readIds.length; i++) {
                                    var readId = this.config.states[state].read[readIds[i]];
                                    if (typeof readId.before !== 'function') {
                                        this.config.states[state].read[readIds[i]].before = function (device, value, callback) {
                                            callback()
                                        };
                                    }
                                    if (typeof readId.after !== 'function') {
                                        this.config.states[state].read[readIds[i]].after = function (device, value) {
                                        };
                                    }
                                }
                                var writeIds = Object.keys(this.config.states[state].write);
                                for (i = 0; i < writeIds.length; i++) {
                                    var writeId = this.config.states[state].write[writeIds[i]];
                                    if (typeof writeId.before !== 'function') {
                                        this.config.states[state].write[writeIds[i]].before = function (device, value, callback) {
                                            callback()
                                        };
                                    }
                                    if (typeof writeId.after !== 'function') {
                                        this.config.states[state].write[writeIds[i]].after = function (device, value) {
                                        };
                                    }
                                }
                                log('normalized state ' + state, 'debug');
                            }
                            
                            VirtualDevice.prototype.connectState = function (state) {
                                log('connecting state ' + state, 'debug');
                                var id = this.namespace + '.' + state;
                            
                                //subscribe to read ids
                                var readIds = Object.keys(this.config.states[state].read);
                                for (var i = 0; i < readIds.length; i++) {
                                    if (getState(readIds[i]).notExist === true) { //check if state exists
                                        log('cannot connect to not existing state: ' + readIds[i], 'warn');
                                        continue;
                                    }
                                    var readObj = this.config.states[state].read[readIds[i]];
                                    var trigger = readObj.trigger || {change: 'any'};
                                    trigger.ack = true;
                                    trigger.id = readIds[i];
                                    this.subRead(trigger, readObj, state);
                                    log('connected ' + readIds[i] + ' to ' + id, 'debug');
                                }
                            
                                //subscribe to this state and write to write ids
                                var writeIds = Object.keys(this.config.states[state].write);
                                var trigger = {id: AdapterPfadVirtuelleGeraete + instance + '.' + this.namespace + '.' + state, change: 'any', ack: false};
                                on(trigger, function (obj) {
                                    "use strict";
                                    log('detected change of ' + state, 'debug');
                                    for (var i = 0; i < writeIds.length; i++) {
                                        let writeObj = this.config.states[state].write[writeIds[i]];
                                        let val = this.convertValue(obj.state.val, writeObj.convert);
                                        let writeId = writeIds[i];
                                        log('executing function before for ' + writeId, 'debug');
                                        writeObj.before(this, val, function (newVal, newDelay) {
                                            if (newVal !== undefined && newVal !== null) val = newVal;
                                            var delay = writeObj.delay;
                                            if (newDelay !== undefined && newDelay !== null) delay = newDelay;
                                            log(newVal + 'writing value ' + val + ' to ' + writeId + ' with delay ' + delay, 'debug');
                                            setStateDelayed(writeId, val, false, delay || 0, true, function () {
                                                log('executing function after for ' + writeId, 'debug');
                                                writeObj.after(this, val);
                                            }.bind(this));
                                        }.bind(this));
                                    }
                                }.bind(this));
                                log('connected ' + state + ' to ' + JSON.stringify(writeIds), 'debug');
                            }
                            
                            VirtualDevice.prototype.subRead = function (trigger, readObj, state) {
                                var func = function (obj) {
                                    var val = this.convertValue(obj.state.val, readObj.convert);
                            
                                    //@todo aggregations
                            
                                    log('executing function before for ' + trigger.id, 'debug');
                                    readObj.before(this, val, function (newVal, newDelay) {
                                        if (newVal !== undefined && newVal !== null) val = newVal;
                                        if (newDelay !== undefined && newDelay !== null) writeObj.delay = newDelay;
                                        log('reading value ' + val + ' to ' + this.namespace + '.' + state, 'debug');
                                        setStateDelayed(this.namespace + '.' + state, val, true, readObj.delay || 0, true, function () {
                                            log('executing function after for ' + trigger.id, 'debug');
                                            readObj.after(this, val);
                                        }.bind(this));
                                    }.bind(this));
                                }.bind(this);
                                func({state: getState(trigger.id)});
                                on(trigger, func);
                            }
                            
                            VirtualDevice.prototype.convertValue = function (val, func) {
                                if (typeof func !== 'function') {
                                    return val;
                                }
                                return func(val);
                            }
                            

                            Beim nächsten Fehler findet er keine Zuweisung für AdapterPfadVirtuelleGeraete:

                            ~~javascript.0	2018-05-22 15:00:29.038	error	at ContextifyScript.Script.runInContext (vm.js:59:29)
                            javascript.0	2018-05-22 15:00:29.038	error	at script.js.common.v-common:87:1
                            javascript.0	2018-05-22 15:00:29.038	error	at new VirtualDevice (script.js.common.v-common:69:10)
                            javascript.0	2018-05-22 15:00:29.037	error	at VirtualDevice.createDevice (script.js.common.v-common:87:18)
                            javascript.0	2018-05-22 15:00:29.037	error	ReferenceError: AdapterPfadVirtuelleGeraete is not defined
                            javascript.0	2018-05-22 15:00:29.036	error	^
                            javascript.0	2018-05-22 15:00:29.036	error	extendObject(AdapterPfadVirtuelleGeraete + instance + '.' + this.namespace, {
                            javascript.0	2018-05-22 15:00:29.035	error	script.js.common.v-common: script.js.common.v-common:87
                            

                            Wohin sollte der zeigen?[/i][/i][/i][/i][/i][/i]

                            1 Antwort Letzte Antwort
                            0
                            • eumatsE Offline
                              eumatsE Offline
                              eumats
                              schrieb am zuletzt editiert von
                              #16

                              In global noch mal folgendes hinzufügen oder das global Skript von oben neu kopieren und einfügen. Da habe ich es korrigiert.

                              var AdapterPfadVirtuelleGeraete = 'javascript.';
                              
                              1 Antwort Letzte Antwort
                              0
                              • S Offline
                                S Offline
                                stephan
                                schrieb am zuletzt editiert von
                                #17

                                @eumats:

                                In global noch mal folgendes hinzufügen oder das global Skript von oben neu kopieren und einfügen. Da habe ich es korrigiert.

                                var AdapterPfadVirtuelleGeraete = 'javascript.';
                                ```` `  Kurze Frage… kann ich den so mit iobroker verbinden oder brauche ich dazu noch extra Hardware... Gruss
                                

                                Gesendet von meinem SM-G928F mit Tapatalk

                                1 Antwort Letzte Antwort
                                0
                                • eumatsE Offline
                                  eumatsE Offline
                                  eumats
                                  schrieb am zuletzt editiert von
                                  #18

                                  @stephan:

                                  Kurze Frage… kann ich den so mit iobroker verbinden oder brauche ich dazu noch extra Hardware... Gruss

                                  Gesendet von meinem SM-G928F mit Tapatalk `

                                  Ich verstehe die Frage nicht…

                                  1 Antwort Letzte Antwort
                                  0
                                  • S Offline
                                    S Offline
                                    stephan
                                    schrieb am zuletzt editiert von
                                    #19

                                    @eumats:

                                    @stephan:

                                    Kurze Frage… kann ich den so mit iobroker verbinden oder brauche ich dazu noch extra Hardware... Gruss

                                    Gesendet von meinem SM-G928F mit Tapatalk `

                                    Ich verstehe die Frage nicht… ` Also ich meine wenn ich mir den Fibaro Schalter kaufe ob ich ihn so mit dem iobroker System verbinden kann.. oder braucht Mann dazu noch etwas..

                                    Gesendet von meinem SM-G928F mit Tapatalk

                                    1 Antwort Letzte Antwort
                                    0
                                    • eumatsE Offline
                                      eumatsE Offline
                                      eumats
                                      schrieb am zuletzt editiert von
                                      #20

                                      Man brauch nach einen Sender/Empfänger der das ZWAVE Protokoll spricht.

                                      Siehe https://github.com/ioBroker/ioBroker.zwave/ -> Tested Hardware

                                      1 Antwort Letzte Antwort
                                      0
                                      • S Offline
                                        S Offline
                                        stephan
                                        schrieb am zuletzt editiert von
                                        #21

                                        Und was welchen würde man da empfehlen.. @eumats:

                                        Man brauch nach einen Sender/Empfänger der das ZWAVE Protokoll spricht.

                                        Siehe https://github.com/ioBroker/ioBroker.zwave/ -> Tested Hardware `

                                        Gesendet von meinem SM-G928F mit Tapatalk

                                        1 Antwort Letzte Antwort
                                        0
                                        • AlCalzoneA Offline
                                          AlCalzoneA Offline
                                          AlCalzone
                                          Developer
                                          schrieb am zuletzt editiert von
                                          #22

                                          @stephan:

                                          Und was welchen würde man da empfehlen.. `

                                          Hast du einen Raspberry, hat der noch den GPIO-Port frei, und willst du den nicht für einen anderen Empfänger verwenden?

                                          – ja: => RazBerry-Platine

                                          -- nein: => USB-Stick

                                          Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

                                          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
                                          FAQ Cloud / IOT
                                          HowTo: Node.js-Update
                                          HowTo: Backup/Restore
                                          Downloads
                                          BLOG

                                          898

                                          Online

                                          32.5k

                                          Benutzer

                                          81.8k

                                          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