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. ioBroker Allgemein
  4. SwitchBot Blind Tilts

NEWS

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    5
    1
    19

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

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    24
    1
    1.7k

SwitchBot Blind Tilts

Geplant Angeheftet Gesperrt Verschoben ioBroker Allgemein
20 Beiträge 2 Kommentatoren 1.6k Aufrufe 3 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.
  • grrfieldG grrfield

    Ich habe bei mir einige SwitchBot Blind Tilts an einem Hub Mini am Laufen und nach einer Möglichkeit gesucht, diese über ioBroker zu steuern. Leider sind die Blind Tilts nicht im SwitchBot-Adapter enthalten, der auch schon einige Zeit nicht mehr aktualisiert wurde und, soweit ich gesehen habe, auf einer alten SwitchBot API basiert. Ich habe mir deswegen ein Skript zur Ansteuerung der Blind Tilts geschrieben und möchte das hier zur Verfügung stellen. Das Skript läßt sich sicher auch für andere SwitchBot-Devices erweitern, Informationen dazu können unter https://github.com/OpenWonderLabs/SwitchBotAPI gefunden werden - ich habe aber nur die Blind Tilts und kann das daher nicht testen.

    Das Skript benötigt API-Token und API-Secret - die erhält man aus der SwitchBot-App unter
    'Profil' - 'Einstellungen' - dort 10 x auf 'App Version' tippen - 'Optionen für Entwickler' erscheint - dort auf 'Token erhalten'
    tippen. Nach dem ersten Aufruf werden unter
    '0_userdata.0.SwitchBot.BlindTilts'
    Devices für die einzelnen Blind Tilts angelegt. Dazu muß im Javascript-Adapter 'Kommando "setObject" erlauben' angekreuzt sein.

    Mit dem State
    '0_userdata.0.SwitchBot.BlindTilts.Jalousiename.LEVEL' ('Jalousiename ' ist der in der SwitchBot-App vergebene Name)
    kann der Blind Tilt mit einem beliebigen Prozentsatz angesteuert werden:
    0% ist ganz geschlossen nach unten, 50% ist offen (gerade), 100% ist ganz geschlossen nach oben. Der State
    '0_userdata.0.SwitchBot.BlindTilts.Jalousiename.slidePosition'
    zeigt die aktuelle Position an und wird nach einiger Zeit aktualisiert. Das Skript liest noch einige andere Informationen aus, die ich aber eigentlich nicht benötige.

    Hier ist das Skript versteckt:

    /**
     * SwitchBot v0.1.2
     * Legt Datenstrukturen zur Steuerung von SwitchBot-Gerätenunter 'SwitchBot' an
     * und ermöglicht die Stuerung der SwitchBot-Devices.
     * - derzeit implementiert: SwitchBot Blind Tilts unter 'SwitchBot.BlindTilt'
     *   Steuerung der Jalousien über 'SwitchBot.BlindTilt'+deviceName+LEVEL
     *   LEVEL:     0% - unten        (closeDown)
     *             50% - offen        (fullyOpen)
     *            100% - geschlossen  (closeUp)
     * 
     * s. https://github.com/OpenWonderLabs/SwitchBotAPI
     * 
     * - kann auf weitere Devicetypen erweitert werden
     * 
     * Devices werden beim Start des Skripts neu eingelesen
     * - nach Hinzufügen oder Entfernen von Geräten das Skript neu starten!
     * Im Javascript-Adapter 'Kommando "setObject" erlauben' ankreuzen!
     * 
     * v0.1.1:
     *  -   Fehler in debug-Funktion berichtigt
     *  -   Aktualisierungsintervall angepaßt
     *  -   einige kleinere Verbesserungen zur Fehlerbehandlung
     * v0.1.2:
     *  -   Skriptneustart zur Neuinitialisierung bei Verbindungsfehlern
     *      (maximal einmal täglich)
     * v0.1.3:
     *  -   const in Definition der debug-Funktion entfernt
     * 
     * log:     SB013
     * debug:   SB106
     */
    
    const DEBUG=false;
    
    const crypto=require('crypto');
    const https=require('https');
    
    
    /**
     * Einstellungen                                //Defaults
     */
    
    // SwitchBot API [string]
    // aus SwitchBot-App:
    // 'Profil' - 'Einstellungen' - 10 x auf 'App Version' tippen - 'Optionen für Entwickler' erscheint - dort auf 'Token erhalten'  tippen
    const token='XXXXX';
    const secret='XXXXX';
    
    // Datenstruktur
    const switchBot='0_userdata.0.SwitchBot.';      // muß auf 'SwitchBot.' enden!
    const blindTilts=switchBot+'BlindTilts.';       // muß auf '.' enden!
    const hubs=switchBot+'hubs.';                   // muß auf '.' enden!
    
    // maximale Bewegungsdauer einer Jalousie [s]
    const maxTiltTime=35;                           //35
    
    // Aktualisierungsintervall wird automatisch korrigiert, falls zu klein [min]
    // max. 1000 API-Calls am Tag -> bei Anzahl der Gaeräte = 4:
    // größer als 60/(1000/Anzahl/24) = 6
    var devInterval=10;                             //10
    
    // Wartezeit für die Abfrage der Devices [ms]
    const devWaitTime=500;                          //500
    
    // maximale Anzahl von Versuchen zum Initialisieren [integer]
    const maxConnTrials=5;                          //5
    
    // Wartezeit für neuen Verbindungsversuch [ms]
    const connWaitTime=2000;                        //2000
    
    
    /**
     * Initialisierung
     */
    
    /**
     * debug() ist bei mir eine globale Funktion
     */
    if(typeof debug == 'undefined') {
        /**
         * Gibt dbmsg aus, wenn DEBUG=true gesetzt ist
         * @param   {string}    dbgmsg      Meldung, die ausgegeben werden soll
         */
        debug=function(dbgmsg)
        {
            if(DEBUG) log(dbgmsg);
        }
    }
    
    var blindDevices;                   // Array mit allen BlindTilt-Device-Namen
    // ... Hier Arrays für andere Devices anlegen
    var iNsiID;                         // Intervall ID zum checken der States in initDeviceList()
    var signTime;                       // Signaturzeit
    var sign;                           // Signatur
    const nonce='requestID';            // requestID
    const startDate=new Date();         // Startzeit des Skriptes für Neustart nach einem Tag bei Verbindungsfehlern
    
    let command='';
    let direction='';
    let LEVEL='';
    let deviceType='';
    
    createSignature();
    
    // Inhalt der https-Requests
    const body={
        'deviceType': deviceType,
        'command': command,
        'parameter': direction+';'+LEVEL,
        'commandType': 'command'
    };
    
    // Optionen der https-Requests
    const options={
        hostname: 'api.switch-bot.com',
        port: 443,
        path: '/v1.1/devices',
        method: 'GET',
        headers: {
            'Authorization': token,
            'sign': sign,
            'nonce': nonce,
            't': signTime,
            'Content-Type': 'application/json',
            'Content-Length': JSON.stringify(body).length,
        },
    };
    
    
    /**
     * Main
     */
    
    SBmain();
    
    
    /**
     * Funktionen
     */
    
    /**
     * Initialisiert und überwacht die Devices
     */
    async function SBmain() 
    {
        let errnum=0;
        while(!(await initDeviceList()) && errnum < maxConnTrials) {
            errnum++;
            await timeout(connWaitTime);
        }
        if(errnum >= maxConnTrials) {
            log('SB010 Error initializing SwitchBot devices - stop script', 'error');
            stopScript();
        }
        await timeout(devWaitTime);
        onBlinds();
        // ... onXxxx() - hier weitere Devicetypen überwachen
    }
    
    
    /**
     * Signatur aus token und secret erstellen
     */
    function createSignature()
    {
        signTime=Date.now();
        let data=token+signTime+nonce;
        let signTerm=crypto.createHmac('sha256', secret)
            .update(Buffer.from(data, 'utf-8'))
            .digest();
        sign=signTerm.toString("base64");
    }
    
    
    /**
     * Erstellt Objekte und States
     */
    async function initDeviceList()
    {
        return new Promise(async resolve => {
            debug('SB101 initDeviceList()');
            createSignature();
            // https-Optionen und Inhalt festlegen
            body.command='devices';
            options.path='/v1.1/devices';
            options.method='GET';
            options.headers['t']=signTime;
            options.headers['sign']=sign;
            options.headers['Content-Length']=JSON.stringify(body).length;
    
            // Alte Objekte löschen
            let switchBotFolder=switchBot.slice(0,switchBot.lastIndexOf('.'));
            // Sicherheitsabfrage, damit bei falsch eingestellter Konstante nicht die falschen States gelöscht werden!
            if(switchBotFolder.slice(switchBotFolder.lastIndexOf('.', switchBot.lastIndexOf('.')-1)+1) == 'SwitchBot') {
                await deleteObjectAsync(switchBotFolder, true);
            }
            // Blind Tilt Devices abfragen
            let blindNumber=0;
            let req=https.request(options, res => {
                if(res.statusCode == 200) {
                    let cont='';
                    res.on('data', chunk => {
                        cont+=chunk.toString();     // convert Buffer to string
                    });
                    res.on('end', async () => {
                        req.end();
                        let device=JSON.parse(cont);
                        let deviceNumber=(device.body.deviceList.length != undefined ? device.body.deviceList.length : 0);
                        // Korrektur des Abfrageintervalls, damit 1000 API-Calls nicht überschritten werden
                        if(devInterval < Math.floor(60/(1000/(deviceNumber+1)/24))) {
                            devInterval=Math.floor(60/(1000/(deviceNumber+1)/24));
                            log('SB012 '+deviceNumber+' Geräte gefunden - Aktualisierungsintervall angepaßt auf '+devInterval+' min');
                        }
                        // gefundene Devices durchgehen
                        for(let i=0; i < deviceNumber; i++) {
                            let deviceId=device.body.deviceList[i]['deviceId'];
                            let deviceName=device.body.deviceList[i]['deviceName'].replace(/ /g, "");
                            let deviceType=device.body.deviceList[i]['deviceType'];
                            debug('SB102 device: '+deviceName+', '+deviceId+', '+deviceType);
                            // für jedes Blind Tilt eine Objektstruktur erstellen
                            if(deviceType == 'Blind Tilt') {
                                blindNumber++;
                                await createStateAsync(blindTilts+deviceName);
                                let btObj=getObject(blindTilts+deviceName);
                                btObj.type='device';
                                btObj.common.name=deviceName;
                                btObj.common.role='';
                                await setObjectAsync(blindTilts+deviceName, btObj);
                                await createStateAsync(blindTilts+deviceName+'.ID', deviceId, {type: 'string', name: 'Device ID'});
                                await createStateAsync(blindTilts+deviceName+'.direction', {type: 'string', name: 'Richtung'});
                                await createStateAsync(blindTilts+deviceName+'.slidePosition', {type: 'number', unit: '%', name: 'Slide Position'});
                                await createStateAsync(blindTilts+deviceName+'.battery', {type: 'number', unit: '%', name: 'Batterie'});   // nur grobe Schritte: 100%, 50%
                                await createStateAsync(blindTilts+deviceName+'.message', {type: 'string', name: 'Message'});
                                await timeout(devWaitTime);
                                await getBlindStatus(deviceName);
                                let position=await getStateAsync(blindTilts+deviceName+'.slidePosition');
                                await createStateAsync(blindTilts+deviceName+'.LEVEL', position.val, {
                                    type: 'number', 
                                    unit: '%', 
                                    name: 'Position (0: unten, 50: offen, 100: oben)',
                                    smartName: {
                                        de: 'Jalousie_'+deviceName.substring(8, 9).toUpperCase()+deviceName.substring(9), 
                                        smartType: 'SWITCH'
                                    }
                                });
                            } else if(deviceType == 'Hub Mini') {
                                await createStateAsync(hubs+deviceName);
                                let btObj=getObject(hubs+deviceName);
                                btObj.type='device';
                                btObj.common.name=deviceName;
                                btObj.common.role='';
                                await setObjectAsync(hubs+deviceName, btObj);
                                await createStateAsync(hubs+deviceName+'.ID', deviceId, {type: 'string', name: 'Device ID'});
                                await createStateAsync(hubs+deviceName+'.enableCloudService', {type: 'string', name: 'Enable Cloud Service'});
                            } // else ... Hier andere Devicetypen eintragen
                        }
                        // Blind Tilt ID in Array schreiben
                        blindDevices=new Array(blindNumber);
                        $(blindTilts+'*.ID').each((id, i) => {
                            blindDevices[i]=id.slice(id.lastIndexOf('.', id.lastIndexOf('.')-1)+1, id.lastIndexOf('.'));
                        });
                        log('SB001 initDeviceList: '+blindNumber+' blind'+(blindNumber != 1 ? 's' :'')+' found');
                        // ... Hier Array für andere Devicetypen befüllen
                        resolve(true);
                    });
                } else {
                    log('SB002 initDeviceList: https.request error - statusCode: '+res.statusCode, 'warn');
                    resolve(false);
                }
            });
            // https-Request ausführen
            req.write(JSON.stringify(body));
            clearInterval(iNsiID);
            // alle devInterval Minuten die States der Blinds aktualisieren
            iNsiID=setInterval(async() => {
                for(let i=0; i < blindDevices.length; i++) {
                    await getBlindStatus(blindDevices[i]);
                }
                // ... Hier States füe andere Devices aktualisieren
            }, devInterval*60*1000);
        });
    }
    
    
    // Funktionen für BlindTilts
    
    /**
     * Ermittelt den Status der Jalousien und schreibt ihn in die States
     * @param   {string}    deviceName  Name der Jalousie
     */
    async function getBlindStatus(deviceName)
    { 
        return new Promise(resolve => {
            debug('SB103 getBlindStatus('+deviceName+')');
            createSignature();
            // https-Optionen und Inhalt festlegen
            let ID=getState(blindTilts+deviceName+'.ID').val
            body.command='status';
            options.path='/v1.1/devices/'+ID+'/status';
            options.method='GET';
            options.headers['t']=signTime;
            options.headers['sign']=sign;
            options.headers['Content-Length']=JSON.stringify(body).length;
    
            // Device abfragen
            let req=https.request(options, res => {
                if(res.statusCode == 200) {
                    let cont='';
                    res.on('data', chunk => {
                        cont+=chunk.toString();     // convert Buffer to string
                    });
                    // Status schreiben
                    res.on('end', async () => {
                        let status=JSON.parse(cont);
                        let direction=status.body['direction'];
                        let slidePosition=status.body['slidePosition'];
                        let battery=status.body['battery'];
                        let message=status.message;
                        debug('SB104 '+deviceName+' direction: '+direction+', slidePosition: '+slidePosition+', battery: '+battery+', message: '+message);
                        await setStateAsync(blindTilts+deviceName+'.direction', direction).catch(() => {log('SB003 '+blindTilts+deviceName+'.direction'+' not found', 'warn');});
                        await setStateAsync(blindTilts+deviceName+'.slidePosition', slidePosition).catch(() => {log('SB004 '+blindTilts+deviceName+'.slidePosition'+' not found', 'warn');});
                        await setStateAsync(blindTilts+deviceName+'.battery', battery).catch(() => {log('SB005 '+blindTilts+deviceName+'.battery'+' not found', 'warn');}); // zur Zeit nur 100%
                        await setStateAsync(blindTilts+deviceName+'.message', message).catch(() => {log('SB006 '+blindTilts+deviceName+'.message'+' not found', 'warn');});
                        req.end();
                        resolve(true);
                    });
                } else {
                    log('SB007 '+deviceName+' getBlindStatus: https.request error - statusCode: '+res.statusCode, 'warn');
                    resolve(false);
                }
            });
            // https-Request ausführen
            if(deviceName != undefined) {
                req.write(JSON.stringify(body));
            } else {
                return(false);
            }
        });
    }
    
    
    /**
     * Setzt die Jalousie auf die gegebene Position
     * @param   {string}    deviceName  Name der Jalousie
     * @param   {number}    level       Position
     */
    async function setBlind(deviceName, level)
    {
        /*
        deviceType  commandType Command	        command parameter	Description
        Blind Tilt	command	    setPosition	    direction;position  e.g. up;60	direction: up/down position: 0~100 (0 means closed, 100 means open, it MUST be set to a multiple of 2. e.g. up;48 or up; 36)
        Blind Tilt	command	    fullyOpen	    default	            Set the position of Blind Tilt to open, equivalent to setting the position to up;100 or down;100
        Blind Tilt	command	    closeUp	        default	            Set the position of Blind Tilt to closed up, equivalent to setting the position to up;0
        Blind Tilt	command	    closeDown	    default	            Set the position of Blind Tilt to closed down, equivalent to setting the position to down;0
        */
        return new Promise(resolve => {
            debug('SB105 setBlind('+deviceName+', '+level+')');
            createSignature();
            // https-Optionen und Inhalt festlegen
            let ID=getState(blindTilts+deviceName+'.ID').val
            body.deviceType=deviceType;
            let command='';
            let direction='';
            let position=100;
            // LEVEL (0..100%) in Blind Tilt Position umrechnen
            if(level <= 0) {
                command='closeDown';
                direction='down';
                position=0;
            } else if(level < 50) {
                command='setPosition'
                direction='down';
                position=2*level;
            } else if(level >= 100) {
                command='closeUp';
                direction='up';
                position=100;
            } else if (level > 50) {
                command='setPosition'
                direction='up';
                position=2*(100-level);
            } else {
                command='fullyOpen'
                position=100;
            }
            body.command=command;
            body.parameter=direction+';'+position;
            body.commandType='command';
            options.path='/v1.1/devices/'+ID+'/commands';
            options.method='POST';
            options.headers['t']=signTime;
            options.headers['sign']=sign;
            options.headers['Content-Length']=JSON.stringify(body).length;
            log('SB008 '+deviceName+' - command: \"'+body.command+'\", parameter: \"'+body.parameter+'\"');
    
            // Befehl ausführen
            let req=https.request(options, res => {
                if(res.statusCode == 200) {
                    res.on('data', d => {
                        debug('SB106 '+deviceName+' data: '+d);
                    });
                    res.on('end', () => {
                        req.end();
                        resolve(true); 
                    });
                } else {
                    log('SB009 '+deviceName+' setBlind: https.request error - statusCode: '+res.statusCode, 'warn');
                    resolve(false);
                }
            });
            // https-Request ausführen
            req.write(JSON.stringify(body));
        });
    }
    
    
    /**
     * Überwacht die Jalousien
     */
    async function onBlinds()
    {
        let dStoID;
        let dIsiID;
    
        // Array mit den LEVEL-States der Blinds erstellen
        let blindLevels=new Array(blindDevices.length);
        for(let i=0; i < blindDevices.length; i++) {
            blindLevels[i]=blindTilts+blindDevices[i]+'.LEVEL';
        }
        on({id: blindLevels, change: 'any'}, async obj => {
            let id=obj.id;
            let name=id.slice(id.lastIndexOf('.', id.lastIndexOf('.')-1)+1, id.lastIndexOf('.'));
            clearTimeout(dStoID);
            clearInterval(iNsiID);
            clearInterval(dIsiID);
            // Jalousie einstellen
            await BlindTilt(name, obj.state.val);
            // neuen Zustand abfragen
            let timefac=Math.abs(getState(blindTilts+name+'.slidePosition').val-obj.state.val)/100+0.2;
            dStoID=setTimeout(async () => {       // Position erst setzen, wenn die Jalousie fertig ist
                await getBlindStatus(name);
                // 2. Versuch, falls es nicht geklappt hat
                if(obj.state.val != getState(blindTilts+name+'.slidePosition').val) {
                    log('SB011 '+name+': '+obj.state.val+' != '+getState(blindTilts+name+'.slidePosition').val+' - new trial...', 'warn');
                    await BlindTilt(name, obj.state.val);
                    // Neustart des Skripts, wenn weiterhin Verbindungsfehler und letzter Neustart länger als einen Tag her
                    if(
                        obj.state.val != getState(blindTilts+name+'.slidePosition').val && 
                        Math.floor((Date.now()-startDate)/1000/3600/24) > 0
                    ) {
                        log('SB013 '+name+': '+obj.state.val+' != '+getState(blindTilts+name+'.slidePosition').val+' - no connection -> restarting Skript...', 'error');
                        setTimeout(() => {
                            runScript();
                        }, connWaitTime);
                    }
                }
            }, maxTiltTime*timefac*1000);
            // alle devInterval Minuten die States aktualisieren
            dIsiID=setInterval(async () => {
                for(let i=0; i < blindDevices.length; i++) {
                    await getBlindStatus(blindDevices[i]);
                }
            }, devInterval*60*1000);
        });
    
    }
    
    
    /**
     * Setzt die Jalousie und aktualisiert die States
     * @param   {string}    deviceName  Name der Jalousie
     * @param   {number}    level       Position
     */
    async function BlindTilt(deviceName, level)
    {
        await setBlind(deviceName, level);
        getBlindStatus(deviceName);
    }
    
    
    // Hier Funktionen getXxxxStatus(), setXxxxx(), onXxxxx(), Xxxxx() für weitere Devicetypen einfügen
    
    
    /**
     * Sleep function
     * @param   {number}    time    Wartezeit [ms]
     */
    function timeout(time) {
        return new Promise(resolve => setTimeout(resolve, time));
    }
    
    
    // ___|\/|
    //  |
    
    


    Update 11.07.23 v0.1.1:

    • Fehler in debug-Funktion berichtigt
    • Aktualisierungsintervall angepaßt
    • einige kleinere Verbesserungen zur Fehlerbehandlung

    Update 13.10.24 v0.1.2:

    • Skriptneustart zur Neuinitialisierung bei Verbindungsfehlern (maximal einmal täglich)

    Update 17.12.24 v0.1.3:

    • const in Definition der debug-Funktion entfernt
    K Offline
    K Offline
    kimukao
    schrieb am zuletzt editiert von
    #2

    @grrfield Genau was ich suche. Habe auch grade einen SwitchBot BlindTilt in Betrieb genommen und festgestellt, dass er nicht vom SwitchBot Adapter unterstützt wird. Bin genau nach Anleitung vorgegangen, habe im Skript API-Token und API-Secret ersetzt, im JavaScript Adapter setObject zugelassen, Skript mehrfach neu gestartet, aber die Datenpunkte werden nicht angelegt. Cloud Service habe ich für die Jalousie in der SwitchBot App aktiviert, Hub Mini ist verbunden. Woran könnte es denn wohl liegen? Muss das Skript einen bestimmten Namen haben oder in einem bestimmten Verzeichnis liegen? Danke 🙏🏻

    grrfieldG 1 Antwort Letzte Antwort
    0
    • K kimukao

      @grrfield Genau was ich suche. Habe auch grade einen SwitchBot BlindTilt in Betrieb genommen und festgestellt, dass er nicht vom SwitchBot Adapter unterstützt wird. Bin genau nach Anleitung vorgegangen, habe im Skript API-Token und API-Secret ersetzt, im JavaScript Adapter setObject zugelassen, Skript mehrfach neu gestartet, aber die Datenpunkte werden nicht angelegt. Cloud Service habe ich für die Jalousie in der SwitchBot App aktiviert, Hub Mini ist verbunden. Woran könnte es denn wohl liegen? Muss das Skript einen bestimmten Namen haben oder in einem bestimmten Verzeichnis liegen? Danke 🙏🏻

      grrfieldG Offline
      grrfieldG Offline
      grrfield
      schrieb am zuletzt editiert von
      #3

      @kimukao Nein, das müßte eigentlich so gehen. Setz bitte mal in Zeile 23 DEBUG=true, starte das Skript und kopiere die Log-Ausgabe - vielleicht kann ich dann etwas sehen.

      K 1 Antwort Letzte Antwort
      0
      • grrfieldG grrfield

        @kimukao Nein, das müßte eigentlich so gehen. Setz bitte mal in Zeile 23 DEBUG=true, starte das Skript und kopiere die Log-Ausgabe - vielleicht kann ich dann etwas sehen.

        K Offline
        K Offline
        kimukao
        schrieb am zuletzt editiert von kimukao
        #4

        @grrfield ```

        
        javascript.0
        2023-07-11 17:19:13.302	error	at Script.runInContext (node:vm:141:12)
        
        javascript.0
        2023-07-11 17:19:13.302	error	at script.js.common.SwitchBot_Blind_Tilts:457:3
        
        javascript.0
        2023-07-11 17:19:13.302	error	at script.js.common.SwitchBot_Blind_Tilts:107:1
        
        javascript.0
        2023-07-11 17:19:13.301	error	at SBmain (script.js.common.SwitchBot_Blind_Tilts:120:19)
        
        javascript.0
        2023-07-11 17:19:13.301	error	at initDeviceList (script.js.common.SwitchBot_Blind_Tilts:153:12)
        
        javascript.0
        2023-07-11 17:19:13.301	error	at new Promise (<anonymous>)
        
        javascript.0
        2023-07-11 17:19:13.301	error	at script.js.common.SwitchBot_Blind_Tilts:154:9
        
        javascript.0
        2023-07-11 17:19:13.301	error	script.js.common.SwitchBot_Blind_Tilts: ReferenceError: debug is not defined
        
        javascript.0
        2023-07-11 17:19:13.301	info	script.js.common.SwitchBot_Blind_Tilts: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
        
        javascript.0
        2023-07-11 17:19:13.299	info	Start javascript script.js.common.SwitchBot_Blind_Tilts
        
        javascript.0
        2023-07-11 17:19:10.938	info	Stop script script.js.common.SwitchBot_Blind_Tilts
        
        javascript.0
        2023-07-11 17:19:07.613	error	at Script.runInContext (node:vm:141:12)
        
        javascript.0
        2023-07-11 17:19:07.613	error	at script.js.common.SwitchBot_Blind_Tilts:457:3
        
        javascript.0
        2023-07-11 17:19:07.613	error	at script.js.common.SwitchBot_Blind_Tilts:107:1
        
        javascript.0
        2023-07-11 17:19:07.613	error	at SBmain (script.js.common.SwitchBot_Blind_Tilts:120:19)
        
        javascript.0
        2023-07-11 17:19:07.613	error	at initDeviceList (script.js.common.SwitchBot_Blind_Tilts:153:12)
        
        javascript.0
        2023-07-11 17:19:07.613	error	at new Promise (<anonymous>)
        
        javascript.0
        2023-07-11 17:19:07.613	error	at script.js.common.SwitchBot_Blind_Tilts:154:9
        
        javascript.0
        2023-07-11 17:19:07.613	error	script.js.common.SwitchBot_Blind_Tilts: ReferenceError: debug is not defined
        
        javascript.0
        2023-07-11 17:19:07.612	info	script.js.common.SwitchBot_Blind_Tilts: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
        
        javascript.0
        2023-07-11 17:19:07.603	info	Start javascript script.js.common.SwitchBot_Blind_Tilts
        
        javascript.0
        2023-07-11 17:19:07.600	info	Stop script script.js.common.SwitchBot_Blind_Tilts
        
        ```
        grrfieldG 1 Antwort Letzte Antwort
        0
        • K kimukao

          @grrfield ```

          
          javascript.0
          2023-07-11 17:19:13.302	error	at Script.runInContext (node:vm:141:12)
          
          javascript.0
          2023-07-11 17:19:13.302	error	at script.js.common.SwitchBot_Blind_Tilts:457:3
          
          javascript.0
          2023-07-11 17:19:13.302	error	at script.js.common.SwitchBot_Blind_Tilts:107:1
          
          javascript.0
          2023-07-11 17:19:13.301	error	at SBmain (script.js.common.SwitchBot_Blind_Tilts:120:19)
          
          javascript.0
          2023-07-11 17:19:13.301	error	at initDeviceList (script.js.common.SwitchBot_Blind_Tilts:153:12)
          
          javascript.0
          2023-07-11 17:19:13.301	error	at new Promise (<anonymous>)
          
          javascript.0
          2023-07-11 17:19:13.301	error	at script.js.common.SwitchBot_Blind_Tilts:154:9
          
          javascript.0
          2023-07-11 17:19:13.301	error	script.js.common.SwitchBot_Blind_Tilts: ReferenceError: debug is not defined
          
          javascript.0
          2023-07-11 17:19:13.301	info	script.js.common.SwitchBot_Blind_Tilts: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
          
          javascript.0
          2023-07-11 17:19:13.299	info	Start javascript script.js.common.SwitchBot_Blind_Tilts
          
          javascript.0
          2023-07-11 17:19:10.938	info	Stop script script.js.common.SwitchBot_Blind_Tilts
          
          javascript.0
          2023-07-11 17:19:07.613	error	at Script.runInContext (node:vm:141:12)
          
          javascript.0
          2023-07-11 17:19:07.613	error	at script.js.common.SwitchBot_Blind_Tilts:457:3
          
          javascript.0
          2023-07-11 17:19:07.613	error	at script.js.common.SwitchBot_Blind_Tilts:107:1
          
          javascript.0
          2023-07-11 17:19:07.613	error	at SBmain (script.js.common.SwitchBot_Blind_Tilts:120:19)
          
          javascript.0
          2023-07-11 17:19:07.613	error	at initDeviceList (script.js.common.SwitchBot_Blind_Tilts:153:12)
          
          javascript.0
          2023-07-11 17:19:07.613	error	at new Promise (<anonymous>)
          
          javascript.0
          2023-07-11 17:19:07.613	error	at script.js.common.SwitchBot_Blind_Tilts:154:9
          
          javascript.0
          2023-07-11 17:19:07.613	error	script.js.common.SwitchBot_Blind_Tilts: ReferenceError: debug is not defined
          
          javascript.0
          2023-07-11 17:19:07.612	info	script.js.common.SwitchBot_Blind_Tilts: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
          
          javascript.0
          2023-07-11 17:19:07.603	info	Start javascript script.js.common.SwitchBot_Blind_Tilts
          
          javascript.0
          2023-07-11 17:19:07.600	info	Stop script script.js.common.SwitchBot_Blind_Tilts
          
          ```
          grrfieldG Offline
          grrfieldG Offline
          grrfield
          schrieb am zuletzt editiert von
          #5

          @kimukao Das mit dem DEBUG hat nicht richtig funktioniert - ich habe bei mir eine globale Funktion debug(), die ich in dem Skript ersetzt habe, da ist wohl ein Fehler drin, den ich bei mir nicht gesehen habe. Ersetze mal in Zeile 441 das != durch == und sende dann nochmal die log-Ausgabe.

          K 1 Antwort Letzte Antwort
          0
          • grrfieldG grrfield

            @kimukao Das mit dem DEBUG hat nicht richtig funktioniert - ich habe bei mir eine globale Funktion debug(), die ich in dem Skript ersetzt habe, da ist wohl ein Fehler drin, den ich bei mir nicht gesehen habe. Ersetze mal in Zeile 441 das != durch == und sende dann nochmal die log-Ausgabe.

            K Offline
            K Offline
            kimukao
            schrieb am zuletzt editiert von kimukao
            #6

            @grrfield ```

            
            javascript.0
            2023-07-11 17:32:43.022	error	at Script.runInContext (node:vm:141:12)
            
            javascript.0
            2023-07-11 17:32:43.022	error	at script.js.common.SwitchBot_Blind_Tilts:457:3
            
            javascript.0
            2023-07-11 17:32:43.022	error	at script.js.common.SwitchBot_Blind_Tilts:107:1
            
            javascript.0
            2023-07-11 17:32:43.022	error	at SBmain (script.js.common.SwitchBot_Blind_Tilts:120:19)
            
            javascript.0
            2023-07-11 17:32:43.022	error	at initDeviceList (script.js.common.SwitchBot_Blind_Tilts:153:12)
            
            javascript.0
            2023-07-11 17:32:43.021	error	at new Promise (<anonymous>)
            
            javascript.0
            2023-07-11 17:32:43.021	error	at script.js.common.SwitchBot_Blind_Tilts:154:9
            
            javascript.0
            2023-07-11 17:32:43.021	error	script.js.common.SwitchBot_Blind_Tilts: ReferenceError: debug is not defined
            
            javascript.0
            2023-07-11 17:32:43.021	info	script.js.common.SwitchBot_Blind_Tilts: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
            
            javascript.0
            2023-07-11 17:32:43.018	info	Start javascript script.js.common.SwitchBot_Blind_Tilts
            
            javascript.0
            2023-07-11 17:32:41.372	info	Stop script script.js.common.SwitchBot_Blind_Tilts
            
            javascript.0
            2023-07-11 17:32:39.779	error	at Script.runInContext (node:vm:141:12)
            
            javascript.0
            2023-07-11 17:32:39.779	error	at script.js.common.SwitchBot_Blind_Tilts:457:3
            
            javascript.0
            2023-07-11 17:32:39.779	error	at script.js.common.SwitchBot_Blind_Tilts:107:1
            
            javascript.0
            2023-07-11 17:32:39.779	error	at SBmain (script.js.common.SwitchBot_Blind_Tilts:120:19)
            
            javascript.0
            2023-07-11 17:32:39.778	error	at initDeviceList (script.js.common.SwitchBot_Blind_Tilts:153:12)
            
            javascript.0
            2023-07-11 17:32:39.778	error	at new Promise (<anonymous>)
            
            javascript.0
            2023-07-11 17:32:39.778	error	at script.js.common.SwitchBot_Blind_Tilts:154:9
            
            javascript.0
            2023-07-11 17:32:39.778	error	script.js.common.SwitchBot_Blind_Tilts: ReferenceError: debug is not defined
            
            javascript.0
            2023-07-11 17:32:39.778	info	script.js.common.SwitchBot_Blind_Tilts: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
            
            javascript.0
            2023-07-11 17:32:39.771	info	Start javascript script.js.common.SwitchBot_Blind_Tilts
            
            javascript.0
            2023-07-11 17:32:39.769	info	Stop script script.js.common.SwitchBot_Blind_Tilts
            
            
            grrfieldG 1 Antwort Letzte Antwort
            0
            • K kimukao

              @grrfield ```

              
              javascript.0
              2023-07-11 17:32:43.022	error	at Script.runInContext (node:vm:141:12)
              
              javascript.0
              2023-07-11 17:32:43.022	error	at script.js.common.SwitchBot_Blind_Tilts:457:3
              
              javascript.0
              2023-07-11 17:32:43.022	error	at script.js.common.SwitchBot_Blind_Tilts:107:1
              
              javascript.0
              2023-07-11 17:32:43.022	error	at SBmain (script.js.common.SwitchBot_Blind_Tilts:120:19)
              
              javascript.0
              2023-07-11 17:32:43.022	error	at initDeviceList (script.js.common.SwitchBot_Blind_Tilts:153:12)
              
              javascript.0
              2023-07-11 17:32:43.021	error	at new Promise (<anonymous>)
              
              javascript.0
              2023-07-11 17:32:43.021	error	at script.js.common.SwitchBot_Blind_Tilts:154:9
              
              javascript.0
              2023-07-11 17:32:43.021	error	script.js.common.SwitchBot_Blind_Tilts: ReferenceError: debug is not defined
              
              javascript.0
              2023-07-11 17:32:43.021	info	script.js.common.SwitchBot_Blind_Tilts: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
              
              javascript.0
              2023-07-11 17:32:43.018	info	Start javascript script.js.common.SwitchBot_Blind_Tilts
              
              javascript.0
              2023-07-11 17:32:41.372	info	Stop script script.js.common.SwitchBot_Blind_Tilts
              
              javascript.0
              2023-07-11 17:32:39.779	error	at Script.runInContext (node:vm:141:12)
              
              javascript.0
              2023-07-11 17:32:39.779	error	at script.js.common.SwitchBot_Blind_Tilts:457:3
              
              javascript.0
              2023-07-11 17:32:39.779	error	at script.js.common.SwitchBot_Blind_Tilts:107:1
              
              javascript.0
              2023-07-11 17:32:39.779	error	at SBmain (script.js.common.SwitchBot_Blind_Tilts:120:19)
              
              javascript.0
              2023-07-11 17:32:39.778	error	at initDeviceList (script.js.common.SwitchBot_Blind_Tilts:153:12)
              
              javascript.0
              2023-07-11 17:32:39.778	error	at new Promise (<anonymous>)
              
              javascript.0
              2023-07-11 17:32:39.778	error	at script.js.common.SwitchBot_Blind_Tilts:154:9
              
              javascript.0
              2023-07-11 17:32:39.778	error	script.js.common.SwitchBot_Blind_Tilts: ReferenceError: debug is not defined
              
              javascript.0
              2023-07-11 17:32:39.778	info	script.js.common.SwitchBot_Blind_Tilts: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
              
              javascript.0
              2023-07-11 17:32:39.771	info	Start javascript script.js.common.SwitchBot_Blind_Tilts
              
              javascript.0
              2023-07-11 17:32:39.769	info	Stop script script.js.common.SwitchBot_Blind_Tilts
              
              
              grrfieldG Offline
              grrfieldG Offline
              grrfield
              schrieb am zuletzt editiert von
              #7

              @kimukao debug() geht immer noch nicht - das hatte ich bei mir so nicht getestet. Probier mal dieses geänderte Skript (Dein API-Token und Secret wieder einsetzen und DEBUG=true einstellen)

              /**
              * SwitchBot v0.1.1
              * Legt Datenstrukturen zur Steuerung von SwitchBot-Gerätenunter 'SwitchBot' an
              * und ermöglicht die Stuerung der SwitchBot-Devices.
              * - derzeit implementiert: SwitchBot Blind Tilts unter 'SwitchBot.BlindTilt'
              *   Steuerung der Jalousien über 'SwitchBot.BlindTilt'+deviceName+LEVEL
              *   LEVEL:     0% - unten        (closeDown)
              *             50% - offen        (fullyOpen)
              *            100% - geschlossen  (closeUp)
              * 
              * s. https://github.com/OpenWonderLabs/SwitchBotAPI
              * 
              * - kann auf weitere Devicetypen erweitert werden
              * 
              * Devices werden beim Start des Skripts neu eingelesen
              * - nach Hinzufügen oder Entfernen von Geräaten das Skript neu starten!
              * Im Javascript-Adapter 'Kommando "setObject" erlauben' ankreuzen!
              * 
              * log:     SB012
              * debug:   SB106
              */
              
              DEBUG=false;
              
              const crypto=require('crypto');
              const https=require('https');
              
              
              /**
              * Einstellungen                                //Defaults
              */
              
              // SwitchBot API [string]
              // aus SwitchBot-App:
              // 'Profil' - 'Einstellungen' - 10 x auf 'App Version' tippen - 'Optionen für Entwickler' erscheint - dort auf 'Token erhalten'  tippen
              const token='XXXX';
              const secret='XXXX';
              
              // Datenstruktur
              const switchBot='0_userdata.0.SwitchBot.';      // muß auf 'SwitchBot.' enden!
              const blindTilts=switchBot+'BlindTilts.';       // muß auf '.' enden!
              const hubs=switchBot+'hubs.';                   // muß auf '.' enden!
              
              // maximale Bewegungsdauer einer Jalousie [s]
              const maxTiltTime=35;                           //35
              
              // Aktualisierungsintervall wird automatisch korrigiert, falls zu klein [min]
              // max. 1000 API-Calls am Tag -> bei Anzahl der Geräte = 4:
              // größer als 60/(1000/Anzahl/24) = 6
              var devInterval=10;                             //10
              
              // Wartezeit für die Abfrage der Devices [ms]
              const devWaitTime=500;                          //500
              
              // maximale Anzahl von Versuchen zum Initialisieren [integer]
              const maxConnTrials=5;                          //5
              
              // Wartezeit für neúen Verbindungsversuch [ms]
              const connWaitTime=2000;                        //2000
              
              
              /**
              * Initialisierung
              */
              
              /**
              * Gibt dbmsg aus, wenn DEBUG=true gesetzt ist
              * @param   {string}    dbgmsg      Meldung, die ausgegeben werden soll
              */
              const debug=function(dbgmsg)
              {
                 if(DEBUG) log(dbgmsg);
              }
              
              var blindDevices;           // Array mit allen BlindTilt-Device-Namen
              // ... Hier Arrays für andere Devices anlegen
              var iNsiID;                 // Intervall ID zum checken der States in initDeviceList()
              var signTime;               // Signaturzeit
              var sign;                   // Signatur
              const nonce='requestID';    // requestID
              
              let command='';
              let direction='';
              let LEVEL='';
              let deviceType='';
              
              createSignature();
              
              // Inhalt der https-Requests
              const body={
                 'deviceType': deviceType,
                 'command': command,
                 'parameter': direction+';'+LEVEL,
                 'commandType': 'command'
              };
              
              // Optionen der https-Requests
              const options={
                 hostname: 'api.switch-bot.com',
                 port: 443,
                 path: '/v1.1/devices',
                 method: 'GET',
                 headers: {
                     'Authorization': token,
                     'sign': sign,
                     'nonce': nonce,
                     't': signTime,
                     'Content-Type': 'application/json',
                     'Content-Length': JSON.stringify(body).length,
                 },
              };
              
              
              /**
              * Main
              */
              
              SBmain();
              
              
              /**
              * Funktionen
              */
              
              /**
              * Initialisiert und überwacht die Devices
              */
              async function SBmain() 
              {
                 let errnum=0;
                 while(!(await initDeviceList()) && errnum < maxConnTrials) {
                     errnum++;
                     await timeout(connWaitTime);
                 }
                 if(errnum >= maxConnTrials) {
                     log('SB010 Error initializing SwitchBot devices - stop script', 'error');
                     stopScript();
                 }
                 await timeout(devWaitTime);
                 onBlinds();
                 // ... onXxxx() - hier weitere Devicetypen überwachen
              }
              
              
              /**
              * Signatur aus token und secret erstellen
              */
              function createSignature()
              {
                 signTime=Date.now();
                 let data=token+signTime+nonce;
                 let signTerm=crypto.createHmac('sha256', secret)
                     .update(Buffer.from(data, 'utf-8'))
                     .digest();
                 sign=signTerm.toString("base64");
              }
              
              
              /**
              * Erstellt Objekte und States
              */
              async function initDeviceList()
              {
                 return new Promise(async resolve => {
                     debug('SB101 initDeviceList()');
                     createSignature();
                     // https-Optionen und Inhalt festlegen
                     body.command='devices';
                     options.path='/v1.1/devices';
                     options.method='GET';
                     options.headers['t']=signTime;
                     options.headers['sign']=sign;
                     options.headers['Content-Length']=JSON.stringify(body).length;
              
                     // Alte Objekte löschen
                     let switchBotFolder=switchBot.slice(0,switchBot.lastIndexOf('.'));
                     // Sicherheitsabfrage, damit bei falsch eingestellter Konstante nicht die falschen States gelöscht werden!
                     if(switchBotFolder.slice(switchBotFolder.lastIndexOf('.', switchBot.lastIndexOf('.')-1)+1) == 'SwitchBot') {
                         await deleteObjectAsync(switchBotFolder, true);
                     }
                     // Blind Tilt Devices abfragen
                     let blindNumber=0;
                     let req=https.request(options, res => {
                         if(res.statusCode == 200) {
                             let cont='';
                             res.on('data', chunk => {
                                 cont+=chunk.toString();     // convert Buffer to string
                             });
                             res.on('end', async () => {
                                 req.end();
                                 let device=JSON.parse(cont);
                                 let deviceNumber=(device.body.deviceList.length != undefined ? device.body.deviceList.length : 0);
                                 // Korrektur des Abfrageintervalls, damit 1000 API-Calls nicht überschritten werden
                                 if(devInterval < Math.floor(60/(1000/(deviceNumber+1)/24))) {
                                     devInterval=Math.floor(60/(1000/(deviceNumber+1)/24));
                                     log('SB012 '+deviceNumber+' Geräte gefunden - Aktualisierungsintervall angepaßt auf '+devInterval+' min');
                                 }
                                 // gefundene Devices durchgehen
                                 for(let i=0; i < deviceNumber; i++) {
                                     let deviceId=device.body.deviceList[i]['deviceId'];
                                     let deviceName=device.body.deviceList[i]['deviceName'].replace(/ /g, "");
                                     let deviceType=device.body.deviceList[i]['deviceType'];
                                     debug('SB102 device: '+deviceName+', '+deviceId+', '+deviceType);
                                     // für jedes Blind Tilt eine Objektstruktur erstellen
                                     if(deviceType == 'Blind Tilt') {
                                         blindNumber++;
                                         await createStateAsync(blindTilts+deviceName);
                                         let btObj=getObject(blindTilts+deviceName);
                                         btObj.type='device';
                                         btObj.common.name=deviceName;
                                         btObj.common.role='';
                                         await setObjectAsync(blindTilts+deviceName, btObj);
                                         await createStateAsync(blindTilts+deviceName+'.ID', deviceId, {type: 'string', name: 'Device ID'});
                                         await createStateAsync(blindTilts+deviceName+'.direction', {type: 'string', name: 'Richtung'});
                                         await createStateAsync(blindTilts+deviceName+'.slidePosition', {type: 'number', unit: '%', name: 'Slide Position'});
                                         await createStateAsync(blindTilts+deviceName+'.battery', {type: 'number', unit: '%', name: 'Batterie'});   // nur grobe Schritte: 100%, 50%
                                         await createStateAsync(blindTilts+deviceName+'.message', {type: 'string', name: 'Message'});
                                         await timeout(devWaitTime);
                                         await getBlindStatus(deviceName);
                                         let position=await getStateAsync(blindTilts+deviceName+'.slidePosition');
                                         await createStateAsync(blindTilts+deviceName+'.LEVEL', position.val, {type: 'number', unit: '%', name: 'Position (0: unten, 50: offen, 100: oben)'});
                                     } else if(deviceType == 'Hub Mini') {
                                         await createStateAsync(hubs+deviceName);
                                         let btObj=getObject(hubs+deviceName);
                                         btObj.type='device';
                                         btObj.common.name=deviceName;
                                         btObj.common.role='';
                                         await setObjectAsync(hubs+deviceName, btObj);
                                         await createStateAsync(hubs+deviceName+'.ID', deviceId, {type: 'string', name: 'Device ID'});
                                         await createStateAsync(hubs+deviceName+'.enableCloudService', {type: 'string', name: 'Enable Cloud Service'});
                                     } // else ... Hier andere Devicetypen eintragen
                                 }
                                 // Blind Tilt ID in Array schreiben
                                 blindDevices=new Array(blindNumber);
                                 $(blindTilts+'*.ID').each((id, i) => {
                                     blindDevices[i]=id.slice(id.lastIndexOf('.', id.lastIndexOf('.')-1)+1, id.lastIndexOf('.'));
                                 });
                                 log('SB001 initDeviceList: '+blindNumber+' blind'+(blindNumber != 1 ? 's' :'')+' found');
                                 // ... Hier Array für andere Devicetypen befüllen
                                 resolve(true);
                             });
                         } else {
                             log('SB002 initDeviceList: https.request error - statusCode: '+res.statusCode, 'warn');
                             resolve(false);
                         }
                     });
                     // https-Request ausführen
                     req.write(JSON.stringify(body));
                     clearInterval(iNsiID);
                     // alle devInterval Minuten die States der Blinds aktualisieren
                     iNsiID=setInterval(async() => {
                         for(let i=0; i < blindDevices.length; i++) {
                             await getBlindStatus(blindDevices[i]);
                         }
                         // ... Hier States füe andere Devices aktualisieren
                     }, devInterval*60*1000);
                 });
              }
              
              
              // Funktionen für BlindTilts
              
              /**
              * Ermittelt den Status der Jalousien und schreibt ihn in die States
              * @param   {string}    deviceName  Name der Jalousie
              */
              async function getBlindStatus(deviceName)
              { 
                 return new Promise(resolve => {
                     debug('SB103 getBlindStatus('+deviceName+')');
                     createSignature();
                     // https-Optionen und Inhalt festlegen
                     let ID=getState(blindTilts+deviceName+'.ID').val
                     body.command='status';
                     options.path='/v1.1/devices/'+ID+'/status';
                     options.method='GET';
                     options.headers['t']=signTime;
                     options.headers['sign']=sign;
                     options.headers['Content-Length']=JSON.stringify(body).length;
              
                     // Device abfragen
                     let req=https.request(options, res => {
                         if(res.statusCode == 200) {
                             let cont='';
                             res.on('data', chunk => {
                                 cont+=chunk.toString();     // convert Buffer to string
                             });
                             // Status schreiben
                             res.on('end', async () => {
                                 let status=JSON.parse(cont);
                                 let direction=status.body['direction'];
                                 let slidePosition=status.body['slidePosition'];
                                 let battery=status.body['battery'];
                                 let message=status.message;
                                 debug('SB104 '+deviceName+' direction: '+direction+', slidePosition: '+slidePosition+', battery: '+battery+', message: '+message);
                                 await setStateAsync(blindTilts+deviceName+'.direction', direction).catch(() => {log('SB003 '+blindTilts+deviceName+'.direction'+' not found', 'warn');});
                                 await setStateAsync(blindTilts+deviceName+'.slidePosition', slidePosition).catch(() => {log('SB004 '+blindTilts+deviceName+'.slidePosition'+' not found', 'warn');});
                                 await setStateAsync(blindTilts+deviceName+'.battery', battery).catch(() => {log('SB005 '+blindTilts+deviceName+'.battery'+' not found', 'warn');}); // zur Zeit nur 100%
                                 await setStateAsync(blindTilts+deviceName+'.message', message).catch(() => {log('SB006 '+blindTilts+deviceName+'.message'+' not found', 'warn');});
                                 req.end();
                                 resolve(true);
                             });
                         } else {
                             log('SB007 '+deviceName+' getBlindStatus: https.request error - statusCode: '+res.statusCode, 'warn');
                             resolve(false);
                         }
                     });
                     // https-Request ausführen
                     if(deviceName != undefined) {
                         req.write(JSON.stringify(body));
                     } else {
                         return(false);
                     }
                 });
              }
              
              
              /**
              * Setzt die Jalousie auf die gegebene Position
              * @param   {string}    deviceName  Name der Jalousie
              * @param   {number}    level       Position
              */
              async function setBlind(deviceName, level)
              {
                 /*
                 deviceType  commandType Command	        command parameter	Description
                 Blind Tilt	command	    setPosition	    direction;position  e.g. up;60	direction: up/down position: 0~100 (0 means closed, 100 means open, it MUST be set to a multiple of 2. e.g. up;48 or up; 36)
                 Blind Tilt	command	    fullyOpen	    default	            Set the position of Blind Tilt to open, equivalent to setting the position to up;100 or down;100
                 Blind Tilt	command	    closeUp	        default	            Set the position of Blind Tilt to closed up, equivalent to setting the position to up;0
                 Blind Tilt	command	    closeDown	    default	            Set the position of Blind Tilt to closed down, equivalent to setting the position to down;0
                 */
                 return new Promise(resolve => {
                     debug('SB105 setBlind('+deviceName+', '+level+')');
                     createSignature();
                     // https-Optionen und Inhalt festlegen
                     let ID=getState(blindTilts+deviceName+'.ID').val
                     body.deviceType=deviceType;
                     let command='';
                     let direction='';
                     let position=100;
                     // LEVEL (0..100%) in Blind Tilt Position umrechnen
                     if(level <= 0) {
                         command='closeDown';
                         direction='down';
                         position=0;
                     } else if(level < 50) {
                         command='setPosition'
                         direction='down';
                         position=2*level;
                     } else if(level >= 100) {
                         command='closeUp';
                         direction='up';
                         position=100;
                     } else if (level > 50) {
                         command='setPosition'
                         direction='up';
                         position=2*(100-level);
                     } else {
                         command='fullyOpen'
                         position=100;
                     }
                     body.command=command;
                     body.parameter=direction+';'+position;
                     body.commandType='command';
                     options.path='/v1.1/devices/'+ID+'/commands';
                     options.method='POST';
                     options.headers['t']=signTime;
                     options.headers['sign']=sign;
                     options.headers['Content-Length']=JSON.stringify(body).length;
                     log('SB008 '+deviceName+' - command: \"'+body.command+'\", parameter: \"'+body.parameter+'\"');
              
                     // Befehl ausführen
                     let req=https.request(options, res => {
                         if(res.statusCode == 200) {
                             res.on('data', d => {
                                 debug('SB106 '+deviceName+' data: '+d);
                             });
                             res.on('end', () => {
                                 req.end();
                                 resolve(true); 
                             });
                         } else {
                             log('SB009 '+deviceName+' setBlind: https.request error - statusCode: '+res.statusCode, 'warn');
                             resolve(false);
                         }
                     });
                     // https-Request ausführen
                     req.write(JSON.stringify(body));
                 });
              }
              
              
              /**
              * Überwacht die Jalousien
              */
              async function onBlinds()
              {
                 let dStoID;
                 let dIsiID;
              
                 // Array mit den LEVEL-States der Blinds erstellen
                 let blindLevels=new Array(blindDevices.length);
                 for(let i=0; i < blindDevices.length; i++) {
                     blindLevels[i]=blindTilts+blindDevices[i]+'.LEVEL';
                 }
                 on({id: blindLevels, change: 'any'}, async obj => {
                     let id=obj.id;
                     let name=id.slice(id.lastIndexOf('.', id.lastIndexOf('.')-1)+1, id.lastIndexOf('.'));
                     clearTimeout(dStoID);
                     clearInterval(iNsiID);
                     clearInterval(dIsiID);
                     // Jalousie einstellen
                     await BlindTilt(name, obj.state.val);
                     // neuen Zustand abfragen
                     let timefac=Math.abs(getState(blindTilts+name+'.slidePosition').val-obj.state.val)/100+0.2;
                     dStoID=setTimeout(async () => {       // Position erst setzen, wenn die Jalousie fertig ist
                         await getBlindStatus(name);
                         // 2. Versuch, falls es nicht geklappt hat
                         if(obj.state.val != getState(blindTilts+name+'.slidePosition').val) {
                             log('SB011 '+name+': '+obj.state.val+' != '+getState(blindTilts+name+'.slidePosition').val+' - new trial...', 'warn');
                             await BlindTilt(name, obj.state.val);
                         }
                     }, maxTiltTime*timefac*1000);
                     // alle devInterval Minuten die States aktualisieren
                     dIsiID=setInterval(async () => {
                         for(let i=0; i < blindDevices.length; i++) {
                             await getBlindStatus(blindDevices[i]);
                         }
                     }, devInterval*60*1000);
                 });
              
              }
              
              
              /**
              * Setzt die Jalousie und aktualisiert die States
              * @param   {string}    deviceName  Name der Jalousie
              * @param   {number}    level       Position
              */
              async function BlindTilt(deviceName, level)
              {
                 await setBlind(deviceName, level);
                 getBlindStatus(deviceName);
              }
              
              
              // Hier Funktionen getXxxxStatus(), setXxxxx(), onXxxxx(), Xxxxx() für weitere Devicetypen einfügen
              
              
              /**
              * Sleep function
              * @param   {number}    time    Wartezeit [ms]
              */
              function timeout(time) {
                 return new Promise(resolve => setTimeout(resolve, time));
              }
              
              
              // ___|\/|
              //  |
              
              

              K 1 Antwort Letzte Antwort
              0
              • grrfieldG grrfield

                @kimukao debug() geht immer noch nicht - das hatte ich bei mir so nicht getestet. Probier mal dieses geänderte Skript (Dein API-Token und Secret wieder einsetzen und DEBUG=true einstellen)

                /**
                * SwitchBot v0.1.1
                * Legt Datenstrukturen zur Steuerung von SwitchBot-Gerätenunter 'SwitchBot' an
                * und ermöglicht die Stuerung der SwitchBot-Devices.
                * - derzeit implementiert: SwitchBot Blind Tilts unter 'SwitchBot.BlindTilt'
                *   Steuerung der Jalousien über 'SwitchBot.BlindTilt'+deviceName+LEVEL
                *   LEVEL:     0% - unten        (closeDown)
                *             50% - offen        (fullyOpen)
                *            100% - geschlossen  (closeUp)
                * 
                * s. https://github.com/OpenWonderLabs/SwitchBotAPI
                * 
                * - kann auf weitere Devicetypen erweitert werden
                * 
                * Devices werden beim Start des Skripts neu eingelesen
                * - nach Hinzufügen oder Entfernen von Geräaten das Skript neu starten!
                * Im Javascript-Adapter 'Kommando "setObject" erlauben' ankreuzen!
                * 
                * log:     SB012
                * debug:   SB106
                */
                
                DEBUG=false;
                
                const crypto=require('crypto');
                const https=require('https');
                
                
                /**
                * Einstellungen                                //Defaults
                */
                
                // SwitchBot API [string]
                // aus SwitchBot-App:
                // 'Profil' - 'Einstellungen' - 10 x auf 'App Version' tippen - 'Optionen für Entwickler' erscheint - dort auf 'Token erhalten'  tippen
                const token='XXXX';
                const secret='XXXX';
                
                // Datenstruktur
                const switchBot='0_userdata.0.SwitchBot.';      // muß auf 'SwitchBot.' enden!
                const blindTilts=switchBot+'BlindTilts.';       // muß auf '.' enden!
                const hubs=switchBot+'hubs.';                   // muß auf '.' enden!
                
                // maximale Bewegungsdauer einer Jalousie [s]
                const maxTiltTime=35;                           //35
                
                // Aktualisierungsintervall wird automatisch korrigiert, falls zu klein [min]
                // max. 1000 API-Calls am Tag -> bei Anzahl der Geräte = 4:
                // größer als 60/(1000/Anzahl/24) = 6
                var devInterval=10;                             //10
                
                // Wartezeit für die Abfrage der Devices [ms]
                const devWaitTime=500;                          //500
                
                // maximale Anzahl von Versuchen zum Initialisieren [integer]
                const maxConnTrials=5;                          //5
                
                // Wartezeit für neúen Verbindungsversuch [ms]
                const connWaitTime=2000;                        //2000
                
                
                /**
                * Initialisierung
                */
                
                /**
                * Gibt dbmsg aus, wenn DEBUG=true gesetzt ist
                * @param   {string}    dbgmsg      Meldung, die ausgegeben werden soll
                */
                const debug=function(dbgmsg)
                {
                   if(DEBUG) log(dbgmsg);
                }
                
                var blindDevices;           // Array mit allen BlindTilt-Device-Namen
                // ... Hier Arrays für andere Devices anlegen
                var iNsiID;                 // Intervall ID zum checken der States in initDeviceList()
                var signTime;               // Signaturzeit
                var sign;                   // Signatur
                const nonce='requestID';    // requestID
                
                let command='';
                let direction='';
                let LEVEL='';
                let deviceType='';
                
                createSignature();
                
                // Inhalt der https-Requests
                const body={
                   'deviceType': deviceType,
                   'command': command,
                   'parameter': direction+';'+LEVEL,
                   'commandType': 'command'
                };
                
                // Optionen der https-Requests
                const options={
                   hostname: 'api.switch-bot.com',
                   port: 443,
                   path: '/v1.1/devices',
                   method: 'GET',
                   headers: {
                       'Authorization': token,
                       'sign': sign,
                       'nonce': nonce,
                       't': signTime,
                       'Content-Type': 'application/json',
                       'Content-Length': JSON.stringify(body).length,
                   },
                };
                
                
                /**
                * Main
                */
                
                SBmain();
                
                
                /**
                * Funktionen
                */
                
                /**
                * Initialisiert und überwacht die Devices
                */
                async function SBmain() 
                {
                   let errnum=0;
                   while(!(await initDeviceList()) && errnum < maxConnTrials) {
                       errnum++;
                       await timeout(connWaitTime);
                   }
                   if(errnum >= maxConnTrials) {
                       log('SB010 Error initializing SwitchBot devices - stop script', 'error');
                       stopScript();
                   }
                   await timeout(devWaitTime);
                   onBlinds();
                   // ... onXxxx() - hier weitere Devicetypen überwachen
                }
                
                
                /**
                * Signatur aus token und secret erstellen
                */
                function createSignature()
                {
                   signTime=Date.now();
                   let data=token+signTime+nonce;
                   let signTerm=crypto.createHmac('sha256', secret)
                       .update(Buffer.from(data, 'utf-8'))
                       .digest();
                   sign=signTerm.toString("base64");
                }
                
                
                /**
                * Erstellt Objekte und States
                */
                async function initDeviceList()
                {
                   return new Promise(async resolve => {
                       debug('SB101 initDeviceList()');
                       createSignature();
                       // https-Optionen und Inhalt festlegen
                       body.command='devices';
                       options.path='/v1.1/devices';
                       options.method='GET';
                       options.headers['t']=signTime;
                       options.headers['sign']=sign;
                       options.headers['Content-Length']=JSON.stringify(body).length;
                
                       // Alte Objekte löschen
                       let switchBotFolder=switchBot.slice(0,switchBot.lastIndexOf('.'));
                       // Sicherheitsabfrage, damit bei falsch eingestellter Konstante nicht die falschen States gelöscht werden!
                       if(switchBotFolder.slice(switchBotFolder.lastIndexOf('.', switchBot.lastIndexOf('.')-1)+1) == 'SwitchBot') {
                           await deleteObjectAsync(switchBotFolder, true);
                       }
                       // Blind Tilt Devices abfragen
                       let blindNumber=0;
                       let req=https.request(options, res => {
                           if(res.statusCode == 200) {
                               let cont='';
                               res.on('data', chunk => {
                                   cont+=chunk.toString();     // convert Buffer to string
                               });
                               res.on('end', async () => {
                                   req.end();
                                   let device=JSON.parse(cont);
                                   let deviceNumber=(device.body.deviceList.length != undefined ? device.body.deviceList.length : 0);
                                   // Korrektur des Abfrageintervalls, damit 1000 API-Calls nicht überschritten werden
                                   if(devInterval < Math.floor(60/(1000/(deviceNumber+1)/24))) {
                                       devInterval=Math.floor(60/(1000/(deviceNumber+1)/24));
                                       log('SB012 '+deviceNumber+' Geräte gefunden - Aktualisierungsintervall angepaßt auf '+devInterval+' min');
                                   }
                                   // gefundene Devices durchgehen
                                   for(let i=0; i < deviceNumber; i++) {
                                       let deviceId=device.body.deviceList[i]['deviceId'];
                                       let deviceName=device.body.deviceList[i]['deviceName'].replace(/ /g, "");
                                       let deviceType=device.body.deviceList[i]['deviceType'];
                                       debug('SB102 device: '+deviceName+', '+deviceId+', '+deviceType);
                                       // für jedes Blind Tilt eine Objektstruktur erstellen
                                       if(deviceType == 'Blind Tilt') {
                                           blindNumber++;
                                           await createStateAsync(blindTilts+deviceName);
                                           let btObj=getObject(blindTilts+deviceName);
                                           btObj.type='device';
                                           btObj.common.name=deviceName;
                                           btObj.common.role='';
                                           await setObjectAsync(blindTilts+deviceName, btObj);
                                           await createStateAsync(blindTilts+deviceName+'.ID', deviceId, {type: 'string', name: 'Device ID'});
                                           await createStateAsync(blindTilts+deviceName+'.direction', {type: 'string', name: 'Richtung'});
                                           await createStateAsync(blindTilts+deviceName+'.slidePosition', {type: 'number', unit: '%', name: 'Slide Position'});
                                           await createStateAsync(blindTilts+deviceName+'.battery', {type: 'number', unit: '%', name: 'Batterie'});   // nur grobe Schritte: 100%, 50%
                                           await createStateAsync(blindTilts+deviceName+'.message', {type: 'string', name: 'Message'});
                                           await timeout(devWaitTime);
                                           await getBlindStatus(deviceName);
                                           let position=await getStateAsync(blindTilts+deviceName+'.slidePosition');
                                           await createStateAsync(blindTilts+deviceName+'.LEVEL', position.val, {type: 'number', unit: '%', name: 'Position (0: unten, 50: offen, 100: oben)'});
                                       } else if(deviceType == 'Hub Mini') {
                                           await createStateAsync(hubs+deviceName);
                                           let btObj=getObject(hubs+deviceName);
                                           btObj.type='device';
                                           btObj.common.name=deviceName;
                                           btObj.common.role='';
                                           await setObjectAsync(hubs+deviceName, btObj);
                                           await createStateAsync(hubs+deviceName+'.ID', deviceId, {type: 'string', name: 'Device ID'});
                                           await createStateAsync(hubs+deviceName+'.enableCloudService', {type: 'string', name: 'Enable Cloud Service'});
                                       } // else ... Hier andere Devicetypen eintragen
                                   }
                                   // Blind Tilt ID in Array schreiben
                                   blindDevices=new Array(blindNumber);
                                   $(blindTilts+'*.ID').each((id, i) => {
                                       blindDevices[i]=id.slice(id.lastIndexOf('.', id.lastIndexOf('.')-1)+1, id.lastIndexOf('.'));
                                   });
                                   log('SB001 initDeviceList: '+blindNumber+' blind'+(blindNumber != 1 ? 's' :'')+' found');
                                   // ... Hier Array für andere Devicetypen befüllen
                                   resolve(true);
                               });
                           } else {
                               log('SB002 initDeviceList: https.request error - statusCode: '+res.statusCode, 'warn');
                               resolve(false);
                           }
                       });
                       // https-Request ausführen
                       req.write(JSON.stringify(body));
                       clearInterval(iNsiID);
                       // alle devInterval Minuten die States der Blinds aktualisieren
                       iNsiID=setInterval(async() => {
                           for(let i=0; i < blindDevices.length; i++) {
                               await getBlindStatus(blindDevices[i]);
                           }
                           // ... Hier States füe andere Devices aktualisieren
                       }, devInterval*60*1000);
                   });
                }
                
                
                // Funktionen für BlindTilts
                
                /**
                * Ermittelt den Status der Jalousien und schreibt ihn in die States
                * @param   {string}    deviceName  Name der Jalousie
                */
                async function getBlindStatus(deviceName)
                { 
                   return new Promise(resolve => {
                       debug('SB103 getBlindStatus('+deviceName+')');
                       createSignature();
                       // https-Optionen und Inhalt festlegen
                       let ID=getState(blindTilts+deviceName+'.ID').val
                       body.command='status';
                       options.path='/v1.1/devices/'+ID+'/status';
                       options.method='GET';
                       options.headers['t']=signTime;
                       options.headers['sign']=sign;
                       options.headers['Content-Length']=JSON.stringify(body).length;
                
                       // Device abfragen
                       let req=https.request(options, res => {
                           if(res.statusCode == 200) {
                               let cont='';
                               res.on('data', chunk => {
                                   cont+=chunk.toString();     // convert Buffer to string
                               });
                               // Status schreiben
                               res.on('end', async () => {
                                   let status=JSON.parse(cont);
                                   let direction=status.body['direction'];
                                   let slidePosition=status.body['slidePosition'];
                                   let battery=status.body['battery'];
                                   let message=status.message;
                                   debug('SB104 '+deviceName+' direction: '+direction+', slidePosition: '+slidePosition+', battery: '+battery+', message: '+message);
                                   await setStateAsync(blindTilts+deviceName+'.direction', direction).catch(() => {log('SB003 '+blindTilts+deviceName+'.direction'+' not found', 'warn');});
                                   await setStateAsync(blindTilts+deviceName+'.slidePosition', slidePosition).catch(() => {log('SB004 '+blindTilts+deviceName+'.slidePosition'+' not found', 'warn');});
                                   await setStateAsync(blindTilts+deviceName+'.battery', battery).catch(() => {log('SB005 '+blindTilts+deviceName+'.battery'+' not found', 'warn');}); // zur Zeit nur 100%
                                   await setStateAsync(blindTilts+deviceName+'.message', message).catch(() => {log('SB006 '+blindTilts+deviceName+'.message'+' not found', 'warn');});
                                   req.end();
                                   resolve(true);
                               });
                           } else {
                               log('SB007 '+deviceName+' getBlindStatus: https.request error - statusCode: '+res.statusCode, 'warn');
                               resolve(false);
                           }
                       });
                       // https-Request ausführen
                       if(deviceName != undefined) {
                           req.write(JSON.stringify(body));
                       } else {
                           return(false);
                       }
                   });
                }
                
                
                /**
                * Setzt die Jalousie auf die gegebene Position
                * @param   {string}    deviceName  Name der Jalousie
                * @param   {number}    level       Position
                */
                async function setBlind(deviceName, level)
                {
                   /*
                   deviceType  commandType Command	        command parameter	Description
                   Blind Tilt	command	    setPosition	    direction;position  e.g. up;60	direction: up/down position: 0~100 (0 means closed, 100 means open, it MUST be set to a multiple of 2. e.g. up;48 or up; 36)
                   Blind Tilt	command	    fullyOpen	    default	            Set the position of Blind Tilt to open, equivalent to setting the position to up;100 or down;100
                   Blind Tilt	command	    closeUp	        default	            Set the position of Blind Tilt to closed up, equivalent to setting the position to up;0
                   Blind Tilt	command	    closeDown	    default	            Set the position of Blind Tilt to closed down, equivalent to setting the position to down;0
                   */
                   return new Promise(resolve => {
                       debug('SB105 setBlind('+deviceName+', '+level+')');
                       createSignature();
                       // https-Optionen und Inhalt festlegen
                       let ID=getState(blindTilts+deviceName+'.ID').val
                       body.deviceType=deviceType;
                       let command='';
                       let direction='';
                       let position=100;
                       // LEVEL (0..100%) in Blind Tilt Position umrechnen
                       if(level <= 0) {
                           command='closeDown';
                           direction='down';
                           position=0;
                       } else if(level < 50) {
                           command='setPosition'
                           direction='down';
                           position=2*level;
                       } else if(level >= 100) {
                           command='closeUp';
                           direction='up';
                           position=100;
                       } else if (level > 50) {
                           command='setPosition'
                           direction='up';
                           position=2*(100-level);
                       } else {
                           command='fullyOpen'
                           position=100;
                       }
                       body.command=command;
                       body.parameter=direction+';'+position;
                       body.commandType='command';
                       options.path='/v1.1/devices/'+ID+'/commands';
                       options.method='POST';
                       options.headers['t']=signTime;
                       options.headers['sign']=sign;
                       options.headers['Content-Length']=JSON.stringify(body).length;
                       log('SB008 '+deviceName+' - command: \"'+body.command+'\", parameter: \"'+body.parameter+'\"');
                
                       // Befehl ausführen
                       let req=https.request(options, res => {
                           if(res.statusCode == 200) {
                               res.on('data', d => {
                                   debug('SB106 '+deviceName+' data: '+d);
                               });
                               res.on('end', () => {
                                   req.end();
                                   resolve(true); 
                               });
                           } else {
                               log('SB009 '+deviceName+' setBlind: https.request error - statusCode: '+res.statusCode, 'warn');
                               resolve(false);
                           }
                       });
                       // https-Request ausführen
                       req.write(JSON.stringify(body));
                   });
                }
                
                
                /**
                * Überwacht die Jalousien
                */
                async function onBlinds()
                {
                   let dStoID;
                   let dIsiID;
                
                   // Array mit den LEVEL-States der Blinds erstellen
                   let blindLevels=new Array(blindDevices.length);
                   for(let i=0; i < blindDevices.length; i++) {
                       blindLevels[i]=blindTilts+blindDevices[i]+'.LEVEL';
                   }
                   on({id: blindLevels, change: 'any'}, async obj => {
                       let id=obj.id;
                       let name=id.slice(id.lastIndexOf('.', id.lastIndexOf('.')-1)+1, id.lastIndexOf('.'));
                       clearTimeout(dStoID);
                       clearInterval(iNsiID);
                       clearInterval(dIsiID);
                       // Jalousie einstellen
                       await BlindTilt(name, obj.state.val);
                       // neuen Zustand abfragen
                       let timefac=Math.abs(getState(blindTilts+name+'.slidePosition').val-obj.state.val)/100+0.2;
                       dStoID=setTimeout(async () => {       // Position erst setzen, wenn die Jalousie fertig ist
                           await getBlindStatus(name);
                           // 2. Versuch, falls es nicht geklappt hat
                           if(obj.state.val != getState(blindTilts+name+'.slidePosition').val) {
                               log('SB011 '+name+': '+obj.state.val+' != '+getState(blindTilts+name+'.slidePosition').val+' - new trial...', 'warn');
                               await BlindTilt(name, obj.state.val);
                           }
                       }, maxTiltTime*timefac*1000);
                       // alle devInterval Minuten die States aktualisieren
                       dIsiID=setInterval(async () => {
                           for(let i=0; i < blindDevices.length; i++) {
                               await getBlindStatus(blindDevices[i]);
                           }
                       }, devInterval*60*1000);
                   });
                
                }
                
                
                /**
                * Setzt die Jalousie und aktualisiert die States
                * @param   {string}    deviceName  Name der Jalousie
                * @param   {number}    level       Position
                */
                async function BlindTilt(deviceName, level)
                {
                   await setBlind(deviceName, level);
                   getBlindStatus(deviceName);
                }
                
                
                // Hier Funktionen getXxxxStatus(), setXxxxx(), onXxxxx(), Xxxxx() für weitere Devicetypen einfügen
                
                
                /**
                * Sleep function
                * @param   {number}    time    Wartezeit [ms]
                */
                function timeout(time) {
                   return new Promise(resolve => setTimeout(resolve, time));
                }
                
                
                // ___|\/|
                //  |
                
                

                K Offline
                K Offline
                kimukao
                schrieb am zuletzt editiert von
                #8

                @grrfield Vielen, vielen Dank! Jetzt klappt‘s! Datenpunkte wurden angelegt, die Jalousie lässt sich über LEVEL prozentual ansteuern. Super 👍🏻

                grrfieldG 1 Antwort Letzte Antwort
                0
                • K kimukao

                  @grrfield Vielen, vielen Dank! Jetzt klappt‘s! Datenpunkte wurden angelegt, die Jalousie lässt sich über LEVEL prozentual ansteuern. Super 👍🏻

                  grrfieldG Offline
                  grrfieldG Offline
                  grrfield
                  schrieb am zuletzt editiert von
                  #9

                  @kimukao Freut mich - dann update ich gleich noch den ersten Beitrag.

                  K 1 Antwort Letzte Antwort
                  0
                  • grrfieldG grrfield

                    @kimukao Freut mich - dann update ich gleich noch den ersten Beitrag.

                    K Offline
                    K Offline
                    kimukao
                    schrieb am zuletzt editiert von
                    #10

                    @grrfield Bis heute funktionierte die Steuerung meiner Jalousien dank deines Scripts super - mittlerweile mit drei BlindTilts. Aber plötzlich gehts nicht mehr, keine Ahnung, was los ist. Im Log steht, dass die SwitchBot Datenpunkte unter userdata nicht gefunden werden können, tatsächlich sind sie futsch. Neustart des Scripts hilft nicht, hab mich auch in der SwitchBot App abgemeldet und wieder angemeldet, dann nochmal das Script neu gestartet. Trotzdem werden die Datenpunkte nicht mehr angelegt. Hast Du das Problem auch? Haben die was an der API geändert? Wäre dankbar für Hilfe. Danke!

                    grrfieldG 1 Antwort Letzte Antwort
                    0
                    • K kimukao

                      @grrfield Bis heute funktionierte die Steuerung meiner Jalousien dank deines Scripts super - mittlerweile mit drei BlindTilts. Aber plötzlich gehts nicht mehr, keine Ahnung, was los ist. Im Log steht, dass die SwitchBot Datenpunkte unter userdata nicht gefunden werden können, tatsächlich sind sie futsch. Neustart des Scripts hilft nicht, hab mich auch in der SwitchBot App abgemeldet und wieder angemeldet, dann nochmal das Script neu gestartet. Trotzdem werden die Datenpunkte nicht mehr angelegt. Hast Du das Problem auch? Haben die was an der API geändert? Wäre dankbar für Hilfe. Danke!

                      grrfieldG Offline
                      grrfieldG Offline
                      grrfield
                      schrieb am zuletzt editiert von
                      #11

                      @kimukao Bei mir funktioniert alles einwandfrei. Versuch doch mal, das Token und das Secret zu erneuern, vielleicht ist da bei Deinem Account etwas abgelaufen. Wenn das nicht geht, bitte mal DEBUG=true; setzen und die LOG-Ausgabe hier reinstellen.

                      K 1 Antwort Letzte Antwort
                      0
                      • grrfieldG grrfield

                        @kimukao Bei mir funktioniert alles einwandfrei. Versuch doch mal, das Token und das Secret zu erneuern, vielleicht ist da bei Deinem Account etwas abgelaufen. Wenn das nicht geht, bitte mal DEBUG=true; setzen und die LOG-Ausgabe hier reinstellen.

                        K Offline
                        K Offline
                        kimukao
                        schrieb am zuletzt editiert von
                        #12

                        @grrfield Mittlerweile geht wieder alles einwandfrei. Scheint ein temporäres API Problem bei Switchbot gewesen zu sein. Die Token habe ich nicht erneuert. Hat sich also erledigt. Danke trotzdem!

                        grrfieldG 1 Antwort Letzte Antwort
                        0
                        • K kimukao

                          @grrfield Mittlerweile geht wieder alles einwandfrei. Scheint ein temporäres API Problem bei Switchbot gewesen zu sein. Die Token habe ich nicht erneuert. Hat sich also erledigt. Danke trotzdem!

                          grrfieldG Offline
                          grrfieldG Offline
                          grrfield
                          schrieb am zuletzt editiert von
                          #13

                          @kimukao Ich habe vor einiger Zeit noch einen Skriptneustart zur Neuinitialisierung bei Verbindungsfehlern eingefügt - die neue Version habe ich im ersten Post aktualisiert. Wenn Du willst, kannst Du das bei Dir mal testen (Token und Secret müssen wieder in das Skript eingfügt werden).

                          K 1 Antwort Letzte Antwort
                          0
                          • grrfieldG grrfield

                            @kimukao Ich habe vor einiger Zeit noch einen Skriptneustart zur Neuinitialisierung bei Verbindungsfehlern eingefügt - die neue Version habe ich im ersten Post aktualisiert. Wenn Du willst, kannst Du das bei Dir mal testen (Token und Secret müssen wieder in das Skript eingfügt werden).

                            K Offline
                            K Offline
                            kimukao
                            schrieb am zuletzt editiert von kimukao
                            #14

                            @grrfield Heute sind auf einmal die angelegten Datenpunkte im userdata Verzeichnis weg inklusive Switchbot-Ordner. Folgendes habe ich versucht, um das Skript wieder zum Laufen zu bringen:

                            1. Neueste Skriptversion aus dem ersten Post kopiert, mit meinem Token und meiner Secret ID gefüttert
                            2. Token in der Switchbot App zurückgesetzt und erneuerten Token im Skript eingefügt
                            3. In der Switchbot App abgemeldet, wieder angemeldet und Skript neu gestartet

                            Immer kommen diese Fehlermeldungen:

                            
                            javascript.0
                            2024-12-16 23:13:33.613	error	at Script.runInContext (node:vm:149:12)
                            
                            javascript.0
                            2024-12-16 23:13:33.613	error	at script.js.common.Beschattung.SwitchBot_Jalousieroboter:498:3
                            
                            javascript.0
                            2024-12-16 23:13:33.613	error	at script.js.common.Beschattung.SwitchBot_Jalousieroboter:133:1
                            
                            javascript.0
                            2024-12-16 23:13:33.613	error	at SBmain (script.js.common.Beschattung.SwitchBot_Jalousieroboter:146:19)
                            
                            javascript.0
                            2024-12-16 23:13:33.613	error	at initDeviceList (script.js.common.Beschattung.SwitchBot_Jalousieroboter:179:12)
                            
                            javascript.0
                            2024-12-16 23:13:33.613	error	at new Promise (<anonymous>)
                            
                            javascript.0
                            2024-12-16 23:13:33.612	error	at script.js.common.Beschattung.SwitchBot_Jalousieroboter:180:9
                            
                            javascript.0
                            2024-12-16 23:13:33.612	error	script.js.common.Beschattung.SwitchBot_Jalousieroboter: ReferenceError: debug is not defined
                            
                            

                            Bin ich allein mit dem Problem, oder hat SwitchBot etwas an der API geändert? Bis gestern ging‘s ja alles prima…

                            grrfieldG 1 Antwort Letzte Antwort
                            0
                            • K kimukao

                              @grrfield Heute sind auf einmal die angelegten Datenpunkte im userdata Verzeichnis weg inklusive Switchbot-Ordner. Folgendes habe ich versucht, um das Skript wieder zum Laufen zu bringen:

                              1. Neueste Skriptversion aus dem ersten Post kopiert, mit meinem Token und meiner Secret ID gefüttert
                              2. Token in der Switchbot App zurückgesetzt und erneuerten Token im Skript eingefügt
                              3. In der Switchbot App abgemeldet, wieder angemeldet und Skript neu gestartet

                              Immer kommen diese Fehlermeldungen:

                              
                              javascript.0
                              2024-12-16 23:13:33.613	error	at Script.runInContext (node:vm:149:12)
                              
                              javascript.0
                              2024-12-16 23:13:33.613	error	at script.js.common.Beschattung.SwitchBot_Jalousieroboter:498:3
                              
                              javascript.0
                              2024-12-16 23:13:33.613	error	at script.js.common.Beschattung.SwitchBot_Jalousieroboter:133:1
                              
                              javascript.0
                              2024-12-16 23:13:33.613	error	at SBmain (script.js.common.Beschattung.SwitchBot_Jalousieroboter:146:19)
                              
                              javascript.0
                              2024-12-16 23:13:33.613	error	at initDeviceList (script.js.common.Beschattung.SwitchBot_Jalousieroboter:179:12)
                              
                              javascript.0
                              2024-12-16 23:13:33.613	error	at new Promise (<anonymous>)
                              
                              javascript.0
                              2024-12-16 23:13:33.612	error	at script.js.common.Beschattung.SwitchBot_Jalousieroboter:180:9
                              
                              javascript.0
                              2024-12-16 23:13:33.612	error	script.js.common.Beschattung.SwitchBot_Jalousieroboter: ReferenceError: debug is not defined
                              
                              

                              Bin ich allein mit dem Problem, oder hat SwitchBot etwas an der API geändert? Bis gestern ging‘s ja alles prima…

                              grrfieldG Offline
                              grrfieldG Offline
                              grrfield
                              schrieb am zuletzt editiert von grrfield
                              #15

                              @kimukao Gestern gab es auch bei mir Probleme mit den Switchbots mit unzähligen Fehlermeldungen. Heute lief es wieder bis auf einzelne Fehlermeldungen im Log. Ich nehme an, daß gestern der Switchbotserver teilweise nicht erreichbar war.

                              In dem neuen Skript aus dem ersten Post muß in Zeile 82 das const entfernt werden, das war ein Copy-Paste-Fehler, den ich bei mir nicht bemerkt habe. Du kannst es einfach herauslöschen, ich aktualisiere es im ersten Post.

                              Edit: Nach Aktualisierung ist die Zeile 82 nun Zeile 84.

                              K 1 Antwort Letzte Antwort
                              0
                              • grrfieldG grrfield

                                @kimukao Gestern gab es auch bei mir Probleme mit den Switchbots mit unzähligen Fehlermeldungen. Heute lief es wieder bis auf einzelne Fehlermeldungen im Log. Ich nehme an, daß gestern der Switchbotserver teilweise nicht erreichbar war.

                                In dem neuen Skript aus dem ersten Post muß in Zeile 82 das const entfernt werden, das war ein Copy-Paste-Fehler, den ich bei mir nicht bemerkt habe. Du kannst es einfach herauslöschen, ich aktualisiere es im ersten Post.

                                Edit: Nach Aktualisierung ist die Zeile 82 nun Zeile 84.

                                K Offline
                                K Offline
                                kimukao
                                schrieb am zuletzt editiert von kimukao
                                #16

                                @grrfield Danke! Hab das „consr“ entfernt, dennoch kommen nun Fehlermeldungen und das Skript stoppt automatisch:

                                
                                javascript.0
                                2024-12-18 14:32:12.110	info	Stopping script script.js.common.Beschattung.SwitchBot_Jalousieroboter
                                
                                javascript.0
                                2024-12-18 14:32:12.087	error	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB010 Error initializing SwitchBot devices - stop script
                                
                                javascript.0
                                2024-12-18 14:32:12.086	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                
                                javascript.0
                                2024-12-18 14:32:11.923	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                
                                javascript.0
                                2024-12-18 14:32:09.922	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                
                                javascript.0
                                2024-12-18 14:32:09.429	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                
                                javascript.0
                                2024-12-18 14:32:07.428	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                
                                javascript.0
                                2024-12-18 14:32:07.283	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                
                                javascript.0
                                2024-12-18 14:32:05.282	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                
                                javascript.0
                                2024-12-18 14:32:05.134	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                
                                javascript.0
                                2024-12-18 14:32:03.133	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                
                                admin.0
                                2024-12-18 14:32:02.936	info	<== Disconnect system.user.admin from ::ffff:192.168.178.106 javascript
                                
                                javascript.0
                                2024-12-18 14:32:02.756	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                
                                javascript.0
                                2024-12-18 14:32:00.755	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                
                                javascript.0
                                2024-12-18 14:32:00.569	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                                
                                javascript.0
                                2024-12-18 14:32:00.569	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                
                                javascript.0
                                2024-12-18 14:32:00.562	info	Start JavaScript script.js.common.Beschattung.SwitchBot_Jalousieroboter (Javascript/js)
                                
                                javascript.0
                                2024-12-18 14:32:00.508	info	Stopping script script.js.common.Beschattung.SwitchBot_Jalousieroboter
                                
                                

                                Hast du noch eine Idee, was bei mir falsch laufen könnte? Dankeschön

                                EDIT: Hat sich erledigt, hab nochmal Dein Skript aus dem ersten Post kopiert und meine Token+Secret eingesetzt. Jetzt klappt‘s. Wer weiß, wo ich einen Fehler gemacht hatte. Tausend Dank!!!

                                grrfieldG 1 Antwort Letzte Antwort
                                0
                                • K kimukao

                                  @grrfield Danke! Hab das „consr“ entfernt, dennoch kommen nun Fehlermeldungen und das Skript stoppt automatisch:

                                  
                                  javascript.0
                                  2024-12-18 14:32:12.110	info	Stopping script script.js.common.Beschattung.SwitchBot_Jalousieroboter
                                  
                                  javascript.0
                                  2024-12-18 14:32:12.087	error	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB010 Error initializing SwitchBot devices - stop script
                                  
                                  javascript.0
                                  2024-12-18 14:32:12.086	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                  
                                  javascript.0
                                  2024-12-18 14:32:11.923	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                  
                                  javascript.0
                                  2024-12-18 14:32:09.922	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                  
                                  javascript.0
                                  2024-12-18 14:32:09.429	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                  
                                  javascript.0
                                  2024-12-18 14:32:07.428	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                  
                                  javascript.0
                                  2024-12-18 14:32:07.283	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                  
                                  javascript.0
                                  2024-12-18 14:32:05.282	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                  
                                  javascript.0
                                  2024-12-18 14:32:05.134	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                  
                                  javascript.0
                                  2024-12-18 14:32:03.133	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                  
                                  admin.0
                                  2024-12-18 14:32:02.936	info	<== Disconnect system.user.admin from ::ffff:192.168.178.106 javascript
                                  
                                  javascript.0
                                  2024-12-18 14:32:02.756	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                  
                                  javascript.0
                                  2024-12-18 14:32:00.755	warn	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB002 initDeviceList: https.request error - statusCode: 401
                                  
                                  javascript.0
                                  2024-12-18 14:32:00.569	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                                  
                                  javascript.0
                                  2024-12-18 14:32:00.569	info	script.js.common.Beschattung.SwitchBot_Jalousieroboter: SB101 initDeviceList()
                                  
                                  javascript.0
                                  2024-12-18 14:32:00.562	info	Start JavaScript script.js.common.Beschattung.SwitchBot_Jalousieroboter (Javascript/js)
                                  
                                  javascript.0
                                  2024-12-18 14:32:00.508	info	Stopping script script.js.common.Beschattung.SwitchBot_Jalousieroboter
                                  
                                  

                                  Hast du noch eine Idee, was bei mir falsch laufen könnte? Dankeschön

                                  EDIT: Hat sich erledigt, hab nochmal Dein Skript aus dem ersten Post kopiert und meine Token+Secret eingesetzt. Jetzt klappt‘s. Wer weiß, wo ich einen Fehler gemacht hatte. Tausend Dank!!!

                                  grrfieldG Offline
                                  grrfieldG Offline
                                  grrfield
                                  schrieb am zuletzt editiert von
                                  #17

                                  @kimukao Kann wieder am Switchbotserver liegen. Bei mir kamen heute auch viele Fehlermeldungen.

                                  1 Antwort Letzte Antwort
                                  0
                                  • K Offline
                                    K Offline
                                    kimukao
                                    schrieb am zuletzt editiert von
                                    #18

                                    Heute ist wieder der 18. Dezember, nur ein Jahr später. Vielleicht macht SwitchBot da ja jährliche Wartungsarbeiten oder so. Jedenfalls läuft das Skript nicht mehr, obwohl ich keine Änderungen vorgenommen habe. Es beendet sich selbst, auch Versuche, es neu zu starten bleiben erfolglos. Ist das bei Dir auch so, @grrfield ?

                                    grrfieldG 1 Antwort Letzte Antwort
                                    0
                                    • grrfieldG Offline
                                      grrfieldG Offline
                                      grrfield
                                      schrieb am zuletzt editiert von
                                      #19

                                      Kann ich erst heute spät am Abend sehen und morgen mal nachschauen. Gestern lief alles normal.

                                      1 Antwort Letzte Antwort
                                      1
                                      • K kimukao

                                        Heute ist wieder der 18. Dezember, nur ein Jahr später. Vielleicht macht SwitchBot da ja jährliche Wartungsarbeiten oder so. Jedenfalls läuft das Skript nicht mehr, obwohl ich keine Änderungen vorgenommen habe. Es beendet sich selbst, auch Versuche, es neu zu starten bleiben erfolglos. Ist das bei Dir auch so, @grrfield ?

                                        grrfieldG Offline
                                        grrfieldG Offline
                                        grrfield
                                        schrieb am zuletzt editiert von
                                        #20

                                        @kimukao Ich hatte gestern, vorgestern und heute morgen das Log voll mit Fehlermeldungen über mißglückte Verbindungsversuche, die Jalousien gingen aber trotzdem wie gewünscht auf und zu. Heute vormittag habe ich um etwas auszuprobieren das Skript mehrmals neu händisch gestartet, und seit ca. 9:00 Uhr kamen keine Fehler mehr, ohne daß ich etwas geändert hätte. Ich nehme daher an, daß es Probleme im Internet gab - nicht nur bei SwitchBot, ich hatte auch Probleme beim Abrufen meiner E-Mails. Hoffen wir, daß es jetzt stabil bleibt bis zum nächsten Dezember ;-)

                                        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

                                        841

                                        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