Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. ioBroker Allgemein
    4. SwitchBot Blind Tilts

    NEWS

    • Monatsrückblick - April 2025

    • Minor js-controller 7.0.7 Update in latest repo

    • Save The Date: ioBroker@Smart Living Forum Solingen, 14.06.

    SwitchBot Blind Tilts

    This topic has been deleted. Only users with topic management privileges can see it.
    • grrfield
      grrfield last edited by 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 1 Reply Last reply Reply Quote 0
      • K
        kimukao @grrfield last edited by

        @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 🙏🏻

        grrfield 1 Reply Last reply Reply Quote 0
        • grrfield
          grrfield @kimukao last edited by

          @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 Reply Last reply Reply Quote 0
          • K
            kimukao @grrfield last edited by 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
            
            ```
            grrfield 1 Reply Last reply Reply Quote 0
            • grrfield
              grrfield @kimukao last edited by

              @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 Reply Last reply Reply Quote 0
              • K
                kimukao @grrfield last edited by 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
                
                
                grrfield 1 Reply Last reply Reply Quote 0
                • grrfield
                  grrfield @kimukao last edited by

                  @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 Reply Last reply Reply Quote 0
                  • K
                    kimukao @grrfield last edited by

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

                    grrfield 1 Reply Last reply Reply Quote 0
                    • grrfield
                      grrfield @kimukao last edited by

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

                      K 1 Reply Last reply Reply Quote 0
                      • K
                        kimukao @grrfield last edited by

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

                        grrfield 1 Reply Last reply Reply Quote 0
                        • grrfield
                          grrfield @kimukao last edited by

                          @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 Reply Last reply Reply Quote 0
                          • K
                            kimukao @grrfield last edited by

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

                            grrfield 1 Reply Last reply Reply Quote 0
                            • grrfield
                              grrfield @kimukao last edited by

                              @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 Reply Last reply Reply Quote 0
                              • K
                                kimukao @grrfield last edited by 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…

                                grrfield 1 Reply Last reply Reply Quote 0
                                • grrfield
                                  grrfield @kimukao last edited by 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 1 Reply Last reply Reply Quote 0
                                  • K
                                    kimukao @grrfield last edited by 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!!!

                                    grrfield 1 Reply Last reply Reply Quote 0
                                    • grrfield
                                      grrfield @kimukao last edited by

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

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

                                      Support us

                                      ioBroker
                                      Community Adapters
                                      Donate
                                      FAQ Cloud / IOT
                                      HowTo: Node.js-Update
                                      HowTo: Backup/Restore
                                      Downloads
                                      BLOG

                                      642
                                      Online

                                      31.6k
                                      Users

                                      79.4k
                                      Topics

                                      1.3m
                                      Posts

                                      2
                                      17
                                      647
                                      Loading More Posts
                                      • Oldest to Newest
                                      • Newest to Oldest
                                      • Most Votes
                                      Reply
                                      • Reply as topic
                                      Log in to reply
                                      Community
                                      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                      The ioBroker Community 2014-2023
                                      logo