Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. ioBroker Allgemein
    4. Anfrage Tahoma/Somfy IO Adapter

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    Anfrage Tahoma/Somfy IO Adapter

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

      Hallo zusammen,

      und hier das Nikolausgeschenk von mir. Funktionalität ist wieder vollumfänglich enthalten.
      PLUS: Jetzt werden auch Szenarien unterstützt. Die sind im Objektbaum unter 'actionGroups' zu finden.

      Viele Grüße

      var request = require('request');
      
      // enable debugging mode
      //request.debug = true;
      
      var lastEventTime = new Date().getTime();
      
      var rawDeviceData = false;
      var tahomaJar = request.jar();
      var baseRequest = request.defaults({
        headers: {
              'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36'},
        jar: tahomaJar
      });
      
      var tahomaDevices = {};
      var tahomaActionGroups = {};
      var Map_DeviceURL2StateName = {};
      
      var userName = "xxxUSERNAMExxx";
      var passWord = "xxxPASSWORTxxx";
      
      var baseURL = 'https://www.tahomalink.com/enduser-mobile-web/enduserAPI/';
      
      var isConnectedInternal = false;
      let loginInProgress = false;
      
      var eventRegisterID = '-1';
      
      createState('tahoma.connected', false, {
        read: true, 
        write: true, 
        name: "connection status of tahoma", 
        type: "boolean", 
        def: false
      });
      
      createOrUpdateState('tahoma.update', false, {
          read: true, 
          write: true,
          role: "button"
      });
      on('javascript.0.tahoma.update', function(obj)
      {
          //log("tahoma refresh states requested: " + obj);
          
          if (obj.newState.val)
          {
              getAllStates();   
          }
      });
      
      function isConnected()
      {
          return isConnectedInternal;
      }
      function setConnected(connected)
      {
          isConnectedInternal = connected;
          
          setState('javascript.0.tahoma.connected', connected, true);
      }
      
      function getCreateStateOptions4Widget(widget)
      {
          if (widget === 'PositionableRollerShutter')
          {
              return {
                      "role":  "blind",
              };
          }
          
          if (widget === 'LuminanceSensor')
          {
              return {
                  "role":  "sensor"
              };
          }
          
          return {
                      read: true, 
                      write: false,
                      role: "state"
                  };
      }
      
      function getCreateStateOptions4State(widget, stateName)
      {
          if (stateName === "core:ClosureState" || stateName === "core:TargetClosureState")
          {
              return {
                      "type":  "number",               // optional,  default "number"
                      "read":  true,                   // mandatory, default true
                      "write": true,                   // mandatory, default true
                      "min":   0,                      // optional,  default 0
                      "max":   100,                    // optional,  default 100
                      "unit":  "%",                    // optional,  default %
                      "role":  "level.blind"           // mandatory
                 };
          }
          if (stateName === "core:SlateOrientationState")
          {
              return {
                      "type":  "number",               // optional,  default "number"
                      "read":  true,                   // mandatory, default true
                      "write": true,                   // mandatory, default true
                      "min":   0,                      // optional,  default 0
                      "max":   100,                    // optional,  default 100
                      "unit":  "%",                    // optional,  default %
                      "role":  "level.blind.orientation"           // mandatory
                 };
          }
          if (stateName === "core:LuminanceState")
          {
              return {
                      "type":  "number",               // optional,  default "number"
                      "read":  true,                   // mandatory, default true
                      "write": false,                   // mandatory, default true
                      "min":   0,                      // optional,  default 0
                      "max":   100000,                    // optional,  default 100
                      "unit":  "Lux",                    // optional,  default %
                      "role":  "level.color.luminance"           // mandatory
                 };
          }
          
          return {
                      read: true, 
                      write: false,
                      role: "state"
                  };
      }
      
      function sendPOST(requestPath, payload, callback)
      {
          login(function(err,data)
          {
              if (err)
              {
                  return callback(err, data);
              }
              
              sendInternalPOST(requestPath, payload, callback);
          });
      }
      
      function sendGET(requestPath, payload, callback)
      {
          login(function(err,data)
          {
              if (err)
              {
                  return callback(err, data);
              }
              
              sendInternalGET(requestPath, payload, callback);
          });
      }
      
      function sendInternalGET(requestPath, payload, callback){
          var url = baseURL + requestPath;
            
          var formPayload = null;
          var jsonPayload = null;
          
          jsonPayload = payload;
          
          log("perform " + requestPath + " with payload:" + JSON.stringify(payload), 'debug');
      
          baseRequest.get(
              {
                  url:    url,
                  json:   jsonPayload,
                  form:   formPayload
              }, 
              function(error, response, body) 
              {
                  if (!error && response.statusCode === 200) 
                  {
                      callback(false, body);
                  }
                  else if (response && (response.statusCode === 401 || response.statusCode === 403))
                  {
                      log("error during tahomalink request: " + response.statusText + " ->" + response.statusCode + " retry "  + requestPath, 'error');
                      
                      // session expired?
                      setConnected(false);
                      loginInProgress = false;
      
                      // perform login and send again
                      sendGET(requestPath, payload, callback);
                  }
                  else
                  {
                      log("error during tahomalink request: " + response.statusCode + ": " + error + 
                          ", request path: " + requestPath + " with payload:" + JSON.stringify(payload), 'error');
                      
                      var result = {};        
                      result.error = error;
                      
                      if(typeof response !== "undefined")
                      {
                          log("response status: " + response.statusCode + " " + response.statusText,'debug');
                          
                          result.responseStatusCode = response.statusCode;
                          result.responseStatusText = response.statusText;
                      }
                      
                      callback(true, result);
                  }
          });
      }
      
      function sendInternalPOST(requestPath, payload, callback)
      {
          var url = baseURL + requestPath;
          
          if (requestPath.endsWith("apply"))
          {
              url = baseURL + requestPath + "/highPriority";
          }
          
          var formPayload = null;
          var jsonPayload = null;
          
          if (requestPath === 'login')
          {
              formPayload = payload;
          }
          else
          {
              jsonPayload = payload;
          }
          
          log("perform " + requestPath + " with payload:" + JSON.stringify(payload), 'debug');
      
          baseRequest.post(
              {
                  url:    url,
                  json:   jsonPayload,
                  form:   formPayload
              }, 
              function(error, response, body) 
              {
                  if (!error && response.statusCode === 200) 
                  {
                      if (requestPath === 'login')
                      {
                          callback(false, JSON.parse(body));
                      }
                      else
                      {
                          callback(false, body);
                      }
                  }
                  else if (response && requestPath !== 'logout'
                      && (response.statusCode === 401 || response.statusCode === 403))
                  {
                      log("error during tahomalink request: " + response.statusText + " ->" + response.statusCode + " retry "  + requestPath, 'error');
                      
                      // session expired?
                      setConnected(false);
                      loginInProgress = false;
      
                      // perform login and send again
                      sendPOST(requestPath, payload, callback);
                  }
                  else
                  {
                      log("error during tahomalink request: " + response.statusCode + ": " + error + 
                          ", request path: " + requestPath + " with payload:" + JSON.stringify(payload), 'error');
                      
                      var result = {};        
                      result.error = error;
                      
                      if(typeof response !== "undefined")
                      {
                          log("response status: " + response.statusCode + " " + response.statusText,'debug');
                          
                          result.responseStatusCode = response.statusCode;
                          result.responseStatusText = response.statusText;
                      }
                      
                      callback(true, result);
                  }
          });
      }
      
      function logout(callback)
      {
          var performLogout = isConnected();
          setConnected(false);
          
          if (performLogout)
          {
              sendInternalPOST("logout", {}, function (err, data)
              {
                  callback(err, data);
              });
          }
          else
          {
              callback(false, {});
          }
      }
      
      function login(callback)
      {
          if (isConnected())
          {
               callback(false, {});
               return;
          }
      
          // check for login already started but not yet finished
          if (loginInProgress)
          {
              //log("login in progress, wait 100 msec");
      
              setTimeout(function()
              {
                  login(callback);
              }, 1500);
              return;
          }
      
          loginInProgress = true;
      
          var payload = {'userId': userName, 'userPassword': passWord};
              
          var result = sendInternalPOST("login", payload, function (err, data)
          {
              if (err || !data.success)
              {
                  loginInProgress = false;
                  return callback(true, data);
              }
              
              lastEventTime = new Date().getTime();
              setConnected(true);
              loginInProgress = false;
              
              getUserInfo(function (err,data)
              {
                  if (!err)
                  {
                      return getSetup(callback);
                  }
                  
                  callback(err, data);
              });
          });
      }
      
      function getUserInfo(callback)
      {
          sendGET('enduser/mainAccount', {},function (err, data)
          {
              if (!err)
              {
                  updateData('userdata', data.endUser);
                  
                  callback(false, data);
              }
              else
              {
                  log("enduser/mainAccount failed!", 'error');
              }
              
          });
      }
      
      function updateGateWayData(gateways)
      {   
          for (var i in gateways) 
          {
              var gateway = gateways[i];
              
              updateData(gateway.gatewayId, gateway);
          }
      }
      
      function updateDevices(devices)
      {   
          tahomaDevices = devices;
          
          for (var i in devices) 
          {
              var device = devices[i];
              
              // just set the raw data from tahoma
              updateDevice('devices.' + device.label, device);
          }
      }
      
      function updateDevice(name, deviceData)
      {   
          createOrUpdateState('tahoma.' + name, '',
              getCreateStateOptions4Widget(deviceData.widget));
          
          // device URL
          createOrUpdateState('tahoma.' + name + '.deviceURL', deviceData.deviceURL);
          
          // states
          for (var stateKey in deviceData.states)
          {
              var state = deviceData.states[stateKey];
              
              createOrUpdateState('tahoma.' + name + '.states.' + state.name, 
                  mapValueTahoma2ioBroker(state.name, state.value),
                  getCreateStateOptions4State(deviceData.widget, state.name));
          }
          
           // commands
          for (var commandKey in deviceData.definition.commands)
          {
              var command = deviceData.definition.commands[commandKey];
              
              if (command.nparams === 0)
              {
                  createOrUpdateState('tahoma.' + name + '.commands.' + command.commandName, false, {
                      read: true, 
                      write: true,
                      role: "button"
                  });
              }
          }
                  
          // raw data
          if (rawDeviceData)
          {
              for (var p in deviceData) 
              {
                  var value = deviceData[p];
                  
                  if (typeof(value) === 'object')
                  {
                      updateData('raw.' + name + '.' + p, value);
                  }
                  else
                  {
                      createOrUpdateState('tahoma.raw.' + name + '.' + p, value);
                  }
              }
          }
      }
      
      function updateActionGroups(actionGroups)
      {   
          tahomaActionGroups = actionGroups;
          
          for (var i in actionGroups) 
          {
              var actionGroup = actionGroups[i];
              
              // just set the raw data from tahoma
              updateActionGroup('actionGroups.' + actionGroup.label, actionGroup);
          }
      }
      
      function updateActionGroup(actionGroup, actionGroupData)
      {    
          // Action Group OID
          createOrUpdateState('tahoma.' + actionGroup + '.oid', actionGroupData.oid);
              
          createOrUpdateState('tahoma.' + actionGroup + '.commands.' + 'execute', false, {
              read: true, 
              write: true,
              role: "button"
          });
      }
      
      function mapValueTahoma2ioBroker(stateName, stateValue)
      {
          if (stateName === 'core:ClosureState' || 
              stateName === 'core:TargetClosureState' ||
              stateName === "core:SlateOrientationState" ||
              stateName === "core:LuminanceState"
              )
          {
              stateValue = parseInt(stateValue,10);
          }
      
          return stateValue;
      }       
      
      function mapValueioBroker2Tahoma(stateName, stateValue)
      {
          if (stateName === 'core:ClosureState' || stateName === 'core:TargetClosureState')
          {
              //stateValue = parseInt(stateValue,10);
          }
      
          return stateValue;
      }       
      
      function updateData(type, data)
      {   
          for (var p in data) 
          {
              var value = data[p];
              
              if (typeof(value) === 'object')
              {
                  updateData(type + '.' + p, value);
              }
              else
              {
                  createOrUpdateState('tahoma.' + type + '.' + p, value);
              }
          }
      }
      
      function createOrUpdateState(key, value, options)
      {
          key = key.replace(' ' , '_');
          var state = getState("javascript.0." + key);
          var typeName = "string";
          
          if (value === "true" || value === "false")
          {
              value = value == "true";
              typeName = "boolean";
          } 
          else if (Number.isInteger(value))
          {
              value = parseInt(value,10);
              typeName = "number";
          }
          else if (!isNaN(value))
          {
              value = Number(value);
              typeName="number";
          }
          
          if (state.notExist)
          {
              
              if (typeof(options) === 'undefined')
              {
                  options = {
                      read: true, 
                      write: false,
                      type: typeName
                  };
              }
      
              // create state
              createState(key, value, 0, options);
          }
          else
          {
              setState("javascript.0." + key, value, true);
          }
      }
      
      function getSetup(callback)
      {
          sendGET('setup', {},function (err, data)
          {
              if (!err)
              {
                  updateGateWayData(data.gateways);
                  updateData('location', data.location);
                  updateDevices(data.devices);
                  
                  // delete old devices
                  deleteOldDevices();
                  
                  // update mapping table device URL to state key with label
                  $('javascript.0.tahoma.devices.*.deviceURL').each(function (id, i) 
                  {
                      var state = getState(id);
                      Map_DeviceURL2StateName[state.val] = id.substr(0, id.indexOf(".deviceURL"));
                      
                      //log("set mapping deviceURL to name: " + state.val + " -> " + id.substr(0, id.indexOf(".deviceURL")),'debug');
                  });
                  
                  // refresh
                  refresh(callback);            
              }
              else
              {
                  log("setup failed!",'error');
                  callback(err, {});
              }
          });
      
          sendGET('actionGroups', {},function (err, data)
          {
              if (!err)
              {
                  updateActionGroups(data);          
              }
              else
              {
                  log("actionGroups failed!",'error');
                  callback(err, {});
              }
          });
      }
      
      function refresh(callback){
          sendPOST('/setup/devices/states/refresh', {}, function (err,data)
                  {
                      if (err)
                      {
                          log("refresh device state failed", 'error');
                      }
                      callback(err, {});   
                  });
      }
      
      function refresh(){
          sendPOST('/setup/devices/states/refresh', {}, function (err,data)
                  {
                      if (err)
                      {
                          log("refresh device state failed", 'error');
                      }
                  });
      }
      
      function getAllStates()
      {
          login(function (err, data)
          {
              if (err)
              {
                  return;
              }
          });
      
          if(eventRegisterID === '-1'){
              sendPOST("events/register", {}, function (err,data)
              {
                  if (err)
                  {
                      log("events/register failed", 'error');
                      return;
                  }
      
                  eventRegisterID = data.id;
                  log ("eventRegisterID = " + eventRegisterID);
                  
                  fetchEvents();
              });
          }
          else {
              fetchEvents();
          }
      }
      
      function fetchEvents(){
          refresh();
              
          sendPOST("events/" + eventRegisterID + "/fetch", {}, function (err,data)
          {
              if (err)
              {
                  return;
              }
              var callback;
              
              log ("events/" + eventRegisterID + "/fetch" + "Fetched Data" + data, 'debug');
              updateDeviceStateFromEvent(data);
          });
      }
      
      function updateDeviceStateFromEvent(events)
      {
          for (var i in events) 
          {
              lastEventTime = new Date().getTime();
              var event = events[i];
         
              if (event.name === 'DeviceStateChangedEvent')
              {
                  updateDeviceState(event);
              }
          }
      }
      
      function updateDeviceState(event)
      {
          var deviceURL = event.deviceURL;
          var states = event.deviceStates;
          
          var devicePath = Map_DeviceURL2StateName[deviceURL];
          // tahoma.devices.XXX
          // tahoma.devices.XXX.states.Y
          
          log("got event for device " + devicePath, 'debug');
       
          for (var i in event.deviceStates) 
          {
              var state = event.deviceStates[i];
              var name = state.name;
              var value = mapValueTahoma2ioBroker(name, state.value);
              
              log("found " + devicePath + '.states.' + name + " -> " + value, 'debug');
              setState(devicePath + '.states.' + name, value, true);
          }
      }
      
      function deleteOldDevices()
      {
          var currentTime = new Date().getTime();
          
          $('javascript.0.tahoma.devices.*.lastUpdateTime').each(function (id, i) 
          {
              var state = getState(id);
              var device = id.substr(0, id.indexOf(".lastUpdateTime"));
              
              if (currentTime - state.ts > 5 * 60 * 1000)
              {
                  // update older than 1 minute -> drop
                  log ("found old " + device + " -> " + new Date(state.ts),'debug');
                  
                  $(device + '.*').each(function (id, i) 
                  {
                      log("delete state:" + id, 'debug');
                      deleteState(id);
                  });
              }
          });
      }
      
      on(/^javascript\.0\.tahoma\.devices.*\.commands/,function(obj)
      {
          if (obj.state.val)
          {
            var id = obj.id;
            log("button pressed: " + id + " -> " + JSON.stringify(obj), 'debug');
           
            var commandName = id.substr(id.lastIndexOf(".")+1);
            var deviceURL = getState(id.substr(0, id.indexOf(".commands.")) + ".deviceURL").val;
            
            var payload = {'label':'command ' + commandName + ' from ioBroker',
                'actions':[{
          		'deviceURL': deviceURL,
              	'commands':	[{
          			'name': commandName,
              	    'parameters': []
              	}]}]};
          
              sendPOST("exec/apply", payload, function(err, data)
              {
                  // reset state
                  setState(obj.id, !obj.state.val);
              });
          }
      });
      
      on(/^javascript\.0\.tahoma\.devices.*\.states.core:ClosureState/,function(obj)
      {
          onClosureStateChange(obj);
      });
      on(/^javascript\.0\.tahoma\.devices.*\.states.core:TargetClosureState/,function(obj)
      {
          onClosureStateChange(obj);
      });
      
      function onClosureStateChange(obj)
      {
          if (!obj.newState.ack)
          {
              var id = obj.id;
                //log("closure state changed: " + id + " -> " + JSON.stringify(obj));
               
                var commandName = "setClosure";
                var deviceURL = getState(id.substr(0, id.indexOf(".states.")) + ".deviceURL").val;
                var stateValue = obj.newState.val;
                var roomName = id.substr(id.indexOf('.devices.')+9);
                
                roomName = roomName.substr(0,roomName.indexOf('.states'));
                
                var payload = {'label': roomName + ' - Positioniere auf ' + stateValue + ' % - ioBroker',
                    'actions':[{
              		'deviceURL': deviceURL,
                  	'commands':	[{
              			'name': commandName,
                  	    'parameters': [ mapValueioBroker2Tahoma('core:ClosureState', stateValue) ]
                  	}]}]};
          
                  sendPOST("exec/apply", payload, function(err, data)
                  {
                      // reset state
                      //setState(obj.id, !obj.state.val);
                  });
          }
      };
      
      on(/^javascript\.0\.tahoma\.devices.*\.states.core:SlateOrientationState/,function(obj)
      {
          if (!obj.newState.ack)
          {
              var id = obj.id;
            
            var commandName = "setOrientation";
            var deviceURL = getState(id.substr(0, id.indexOf(".states.")) + ".deviceURL").val;
            var stateValue = obj.newState.val;
            var roomName = id.substr(id.indexOf('.devices.')+9);
                
              roomName = roomName.substr(0,roomName.indexOf('.states'));
            
            //log("slate orientation changed: " + roomName + " -> " + stateValue);
           
            
            var payload = {'label':roomName + ' - Ausrichtung ' + stateValue + ' % - ioBroker',
                'actions':[{
          		'deviceURL': deviceURL,
              	'commands':	[{
          			'name': commandName,
              	    'parameters': [ mapValueioBroker2Tahoma('core:SlateOrientationState', stateValue) ]
              	}]}]};
          
              sendPOST("exec/apply", payload, function(err, data)
              {
                  // reset state
                  //setState(obj.id, !obj.state.val);
              });
              
          }
      });
      
      on({id: /^javascript\.0\.tahoma\.actionGroups.*\.commands.execute/, valNe: false}, function (obj) {
          if (obj.state.val)
          {
              var id = obj.id;
              var oid = getState(id.substr(0, id.indexOf(".commands.")) + ".oid").val;
      
              log(baseURL + "exec/" + oid);
      
              sendPOST("exec/" + oid, "", function(err, data)
              {
                  if (err)
                  {
                      log(baseURL + "exec/" + oid, "error");
                      return;
                  }
              });
          }
      });
      
      // if connected, update state all 5 seconds
      //schedule("*/5 * * * * *", function () 
      // if connected, update state all 10 seconds
      schedule("*/10 * * * * *", function () 
      {
          // if connected, update states
          if (isConnected())
          {
              getAllStates();
              
              if (new Date().getTime() - lastEventTime > 5 * 60 * 1000)
              {
                  // no events within last 60 seconds
                  logout(function () {});
              }
          }
      });
      
      // update state all 10 minutes
      schedule("*/10 * * * *", function () 
      {
          if (new Date().getTime() - lastEventTime > 9 * 60 * 1000)
          {
              log("update tahoma all 10 minutes");
              getAllStates();
          }
      });
      
      onStop(function (callback) {
          logout(function (err, data)
              {
                  callback();
              });
      }, 10000 /*ms*/);
      
      // start script
      getAllStates();
      
      K integer63 G 3 Replies Last reply Reply Quote 2
      • K
        kassmann @blackeagle998 last edited by

        @blackeagle998

        👍🏼 Erledigt

        1 Reply Last reply Reply Quote 0
        • K
          kassmann @thoemmes86 last edited by

          @thoemmes86 sagte in Anfrage Tahoma/Somfy IO Adapter:

          Hallo zusammen,

          und hier das Nikolausgeschenk von mir. Funktionalität ist wieder vollumfänglich enthalten.
          PLUS: Jetzt werden auch Szenarien unterstützt. Die sind im Objektbaum unter 'actionGroups' zu finden.

          Viele Grüße

          Na das war mal ein schönes Nikolausgeschenk. 😁
          Tausend Dank 👏 👏

          1 Reply Last reply Reply Quote 0
          • T
            thoemmes86 last edited by

            Ich habe gerade das Skript in meinem letzten Post aktualisiert.
            War beim Ausführen von Szenarien noch ein Fehler drin. Jedes Szenario konnte nur genau einmal ausgeführt werden. 😵

            1 Reply Last reply Reply Quote 0
            • integer63
              integer63 @thoemmes86 last edited by

              @thoemmes86 Was soll ich sagen - DANKE!

              Funktioniert wieder wie vorher 🙂 Und genau zu diesem "vorher" hätte ich eine Frage: Ich habe das Phänomen, dass wenn ich die Behanghöhe auf einen bestimmten Prozentwert stelle (über core:ClosureState) und der Screen auf diese Position gefahren ist (z. B. von 0% auf 50%), er dann ein paar Sekunden später auf eine andere Position fährt, an der er gerade eben vorbeigefahren ist (z. B. 46%) - wobei dieses "ein Stück zurückfahren" immer ein etwas anderer Wert ist. Ich vermute, dass durch das Abfragen der States noch während der Fahrt, der ClosureState aktualisiert wird und den neuen Wert dann gleich wieder als Auslöser nimmt und ihn anfährt. Könnte das sein? Übrigens ich habe keinen Datenpunkt core:TargetClosureState. Habe nur ich dieses Problem?

              tahoma-ClosureState.png

              1 Reply Last reply Reply Quote 0
              • S
                smartysmart last edited by

                ioBroker ist im kommen und hat schon Systeme verdrängt die länger auf dem Markt sind.
                Warum ?
                Weil ioBroker eine geile Community hat und die Bedienung sehr inuitiv ist.
                Es wird eine Menge unterstützt und es gibt zig verschiedene Videos zu verschiedenen Themen.

                Für mich ist und bleibt ioBroker #1.

                Ein Somfy Adapter darf meiner Meinung nach nicht fehlen. Somfy und Velux sind zwei sehr bekannte Hersteller in ihrem Gebiet, und wir wollen ja noch weiter wachsen, also sollten wir es neuen Usern schmackhaft machen ioBroker zu nutzen.

                Dadurch das Somfy die API öffentlich gemacht hat sollte es für den Developer auch eine machbare Sache sein und der Aufwand sich in Grenzen halten.

                Wenn ein Developer Zeit und Lust hat, dann soll er sich melden. Im Zweifel starten wir noch eine Spendenaktion und versuchen so für den Developer das maximum an Dankbarkeit für seine Leistung zu erbringen.

                1 Reply Last reply Reply Quote 1
                • G
                  gammler2003 @thoemmes86 last edited by

                  @thoemmes86 Genial, vielen Dank für deine Mühe! Das Skript ist genau das, was ich immer gesucht habe.

                  Jedoch ist es so, dass es permanent Warnmeldungen in meinen Log schreibt. Nachfolgend ein kleiner Auszug davon. Kannst du dir erklären, an was das liegt? Was mache ich falsch?

                  Vielen Dank vorab an alle,
                  Steven

                  2020-01-11 10:17:00.157 - warn: javascript.0 (1930) at updateDeviceState (script.js.Produktion.Tahoma-Script:701:9)
                  2020-01-11 10:17:00.157 - warn: javascript.0 (1930) at updateDeviceStateFromEvent (script.js.Produktion.Tahoma-Script:678:13)
                  2020-01-11 10:17:00.158 - warn: javascript.0 (1930) at script.js.Produktion.Tahoma-Script:665:9
                  2020-01-11 10:17:00.158 - warn: javascript.0 (1930) at Request._callback (script.js.Produktion.Tahoma-Script:252:21)
                  2020-01-11 10:17:00.158 - warn: javascript.0 (1930) at Request.self.callback (/opt/iobroker/node_modules/request/request.js:185:22)
                  2020-01-11 10:17:00.158 - warn: javascript.0 (1930) at Request.emit (events.js:210:5)
                  2020-01-11 10:17:00.158 - warn: javascript.0 (1930) at Request. (/opt/iobroker/node_modules/request/request.js:1161:10)
                  2020-01-11 10:17:00.159 - warn: javascript.0 (1930) at Request.emit (events.js:210:5)
                  2020-01-11 10:17:00.159 - warn: javascript.0 (1930) at IncomingMessage. (/opt/iobroker/node_modules/request/request.js:1083:12)
                  2020-01-11 10:17:00.159 - warn: javascript.0 (1930) at Object.onceWrapper (events.js:299:28)
                  2020-01-11 10:17:00.159 - warn: javascript.0 (1930) at IncomingMessage.emit (events.js:215:7)
                  2020-01-11 10:17:00.159 - warn: javascript.0 (1930) at endReadableNT (_stream_readable.js:1184:12)
                  2020-01-11 10:17:00.160 - warn: javascript.0 (1930) at processTicksAndRejections (internal/process/task_queues.js:80:21)
                  2020-01-11 10:17:00.160 - warn: javascript.0 (1930) State "undefined.states.core:RSSILevelState" not found
                  2020-01-11 10:17:00.162 - warn: javascript.0 (1930) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1258:20)
                  2020-01-11 10:17:00.162 - warn: javascript.0 (1930) at updateDeviceState (script.js.Produktion.Tahoma-Script:701:9)
                  2020-01-11 10:17:00.162 - warn: javascript.0 (1930) at updateDeviceStateFromEvent (script.js.Produktion.Tahoma-Script:678:13)
                  2020-01-11 10:17:00.162 - warn: javascript.0 (1930) at script.js.Produktion.Tahoma-Script:665:9
                  2020-01-11 10:17:00.162 - warn: javascript.0 (1930) at Request._callback (script.js.Produktion.Tahoma-Script:252:21)
                  2020-01-11 10:17:00.163 - warn: javascript.0 (1930) at Request.self.callback (/opt/iobroker/node_modules/request/request.js:185:22)
                  2020-01-11 10:17:00.163 - warn: javascript.0 (1930) at Request.emit (events.js:210:5)
                  2020-01-11 10:17:00.163 - warn: javascript.0 (1930) at Request. (/opt/iobroker/node_modules/request/request.js:1161:10)
                  2020-01-11 10:17:00.163 - warn: javascript.0 (1930) at Request.emit (events.js:210:5)
                  2020-01-11 10:17:00.163 - warn: javascript.0 (1930) at IncomingMessage. (/opt/iobroker/node_modules/request/request.js:1083:12)
                  2020-01-11 10:17:00.163 - warn: javascript.0 (1930) at Object.onceWrapper (events.js:299:28)
                  2020-01-11 10:17:00.164 - warn: javascript.0 (1930) at IncomingMessage.emit (events.js:215:7)
                  2020-01-11 10:17:00.164 - warn: javascript.0 (1930) at endReadableNT (_stream_readable.js:1184:12)
                  2020-01-11 10:17:00.164 - warn: javascript.0 (1930) at processTicksAndRejections (internal/process/task_queues.js:80:21)
                  2020-01-11 10:17:00.164 - warn: javascript.0 (1930) State "undefined.states.core:RSSILevelState" not found
                  2020-01-11 10:17:00.166 - warn: javascript.0 (1930) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1258:20)
                  2020-01-11 10:17:00.166 - warn: javascript.0 (1930) at updateDeviceState (script.js.Produktion.Tahoma-Script:701:9)
                  2020-01-11 10:17:00.166 - warn: javascript.0 (1930) at updateDeviceStateFromEvent (script.js.Produktion.Tahoma-Script:678:13)
                  2020-01-11 10:17:00.167 - warn: javascript.0 (1930) at script.js.Produktion.Tahoma-Script:665:9
                  2020-01-11 10:17:00.167 - warn: javascript.0 (1930) at Request._callback (script.js.Produktion.Tahoma-Script:252:21)
                  2020-01-11 10:17:00.171 - warn: javascript.0 (1930) at Request.self.callback (/opt/iobroker/node_modules/request/request.js:185:22)
                  2020-01-11 10:17:00.171 - warn: javascript.0 (1930) at Request.emit (events.js:210:5)
                  2020-01-11 10:17:00.171 - warn: javascript.0 (1930) at Request. (/opt/iobroker/node_modules/request/request.js:1161:10)
                  2020-01-11 10:17:00.171 - warn: javascript.0 (1930) at Request.emit (events.js:210:5)
                  2020-01-11 10:17:00.172 - warn: javascript.0 (1930) at IncomingMessage. (/opt/iobroker/node_modules/request/request.js:1083:12)
                  2020-01-11 10:17:00.172 - warn: javascript.0 (1930) at Object.onceWrapper (events.js:299:28)
                  2020-01-11 10:17:00.172 - warn: javascript.0 (1930) at IncomingMessage.emit (events.js:215:7)
                  2020-01-11 10:17:00.172 - warn: javascript.0 (1930) at endReadableNT (_stream_readable.js:1184:12)
                  2020-01-11 10:17:00.172 - warn: javascript.0 (1930) at processTicksAndRejections (internal/process/task_queues.js:80:21)
                  2020-01-11 10:17:00.173 - warn: javascript.0 (1930) State "undefined.states.core:RSSILevelState" not found
                  2020-01-11 10:17:00.174 - warn: javascript.0 (1930) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1258:20)
                  2020-01-11 10:17:00.175 - warn: javascript.0 (1930) at updateDeviceState (script.js.Produktion.Tahoma-Script:701:9)
                  2020-01-11 10:17:00.175 - warn: javascript.0 (1930) at updateDeviceStateFromEvent (script.js.Produktion.Tahoma-Script:678:13)
                  2020-01-11 10:17:00.175 - warn: javascript.0 (1930) at script.js.Produktion.Tahoma-Script:665:9
                  2020-01-11 10:17:00.175 - warn: javascript.0 (1930) at Request._callback (script.js.Produktion.Tahoma-Script:252:21)
                  2020-01-11 10:17:00.175 - warn: javascript.0 (1930) at Request.self.callback (/opt/iobroker/node_modules/request/request.js:185:22)
                  2020-01-11 10:17:00.176 - warn: javascript.0 (1930) at Request.emit (events.js:210:5)
                  2020-01-11 10:17:00.176 - warn: javascript.0 (1930) at Request. (/opt/iobroker/node_modules/request/request.js:1161:10)
                  2020-01-11 10:17:00.176 - warn: javascript.0 (1930) at Request.emit (events.js:210:5)
                  2020-01-11 10:17:00.176 - warn: javascript.0 (1930) at IncomingMessage. (/opt/iobroker/node_modules/request/request.js:1083:12)
                  2020-01-11 10:17:00.176 - warn: javascript.0 (1930) at Object.onceWrapper (events.js:299:28)
                  2020-01-11 10:17:00.176 - warn: javascript.0 (1930) at IncomingMessage.emit (events.js:215:7)
                  2020-01-11 10:17:00.177 - warn: javascript.0 (1930) at endReadableNT (_stream_readable.js:1184:12)
                  2020-01-11 10:17:00.177 - warn: javascript.0 (1930) at processTicksAndRejections (internal/process/task_queues.js:80:21)
                  
                  snookerap 1 Reply Last reply Reply Quote 0
                  • snookerap
                    snookerap @gammler2003 last edited by snookerap

                    @gammler2003
                    @thoemmes86
                    selbiges bei mir auch
                    Wie muss man es richtig einstellen, damit es funktioniert?

                    1 Reply Last reply Reply Quote 0
                    • StrathCole
                      StrathCole last edited by

                      Soweit ich das mit den Warnungen richtig sehe, ist das ein Problem mit den deviceURLs. Er scheint da etwas nicht zu finden.

                      Ich habe auf Basis des Skripts jetzt einen Adapter entwickelt und dabei auch einige Bugs gefixt (vermutlich auch neue eingebaut 😉 ).

                      https://github.com/StrathCole/ioBroker.tahoma

                      K E 3 Replies Last reply Reply Quote 3
                      • snookerap
                        snookerap last edited by

                        Top, klasse Arbeit!!!
                        Direkt mal instaliert, habe bisher die Rollos über den HAM-Adapter gesteuert.
                        -> dieser hier bringt mir natürlich deutlich mehr Objekt-Werte in den ioBroker

                        Vielen Dank

                        1 Reply Last reply Reply Quote 0
                        • K
                          kassmann @StrathCole last edited by

                          @StrathCole das ist ja mal eine tolle Überraschung, gleich installiert 😊 👍

                          1 Reply Last reply Reply Quote 0
                          • E
                            el_malto @StrathCole last edited by

                            @StrathCole coole Sache.
                            Ist das Skript denn auf der Basis der API die jetzt von Somfy veröffentlich wurde?
                            https://www.somfy.de/ueber-somfy/-so-open-mit-somfy
                            https://developer.somfy.com/somfy-open-api/apis
                            Es macht doch für die Zukunft mehr Sinn gleich die offizielle API zu verwenden.

                            Auf GitHub gibt es auch schon eine Implementierung von der API in Phyton 3. Hilft ja vielleicht auch weiter.
                            https://github.com/tetienne/somfy-open-api

                            Leider habe ich davon überhaupt keine Ahnung.

                            StrathCole 1 Reply Last reply Reply Quote 0
                            • E
                              el_malto @StrathCole last edited by

                              @StrathCole
                              Ich bin einfach mal so frei und verlinke auch dein Thread zum testen hier. Nicht das Feedback dann hier landet und untergeht.

                              Feedback also immer hier posten -> https://forum.iobroker.net/topic/28956/test-adapter-somfy-tahoma-v0-1-x-github

                              1 Reply Last reply Reply Quote 0
                              • StrathCole
                                StrathCole @el_malto last edited by StrathCole

                                @el_malto sagte in Anfrage Tahoma/Somfy IO Adapter:

                                @StrathCole coole Sache.
                                Ist das Skript denn auf der Basis der API die jetzt von Somfy veröffentlich wurde?
                                https://www.somfy.de/ueber-somfy/-so-open-mit-somfy
                                https://developer.somfy.com/somfy-open-api/apis
                                Es macht doch für die Zukunft mehr Sinn gleich die offizielle API zu verwenden.

                                Nein, ist es nicht. Es verwendet die API, die auch die tahomalink Homepage verwendet.
                                Die offizielle API liefert leider auch viel weniger Infos zu den einzelnen Rollläden und Geräten, beispielsweise scheint die Signalstärke (Funk) zu fehlen.
                                Auch gibt es keine Möglichkeit, die ich gesehen hätte, via API auf die "my" Position zu fahren usw.

                                Daher würde ich persönlich derzeit nicht diese API nutzen.

                                @el_malto sagte in Anfrage Tahoma/Somfy IO Adapter:

                                @StrathCole
                                Ich bin einfach mal so frei und verlinke auch dein Thread zum testen hier. Nicht das Feedback dann hier landet und untergeht.

                                Feedback also immer hier posten -> https://forum.iobroker.net/topic/28956/test-adapter-somfy-tahoma-v0-1-x-github

                                Danke, hatte ich vergessen.

                                1 Reply Last reply Reply Quote 1
                                • B
                                  blackeagle998 last edited by

                                  @StrathCole
                                  Wirklich super, dass du diesen Adapter erstellt hast.

                                  Nachdem das Skript nicht mehr lauffähig war, habe ich alles auf den HAM Adapter geändert.
                                  Ich habe deinen Adapter installiert und er läuft fehlerfrei, die Datenpunkte sind alle da.
                                  Testen konnte ich bisher noch nicht wirklich, ich muss das jetzt erstmal alles wieder zurück ändern bzw. ein Parallelskript anlegen ☺

                                  Bisher war mein Problem immer, dass ich nur Befehle für 9 Rollläden auf einmal senden konnte und danach einen Timeout einbauen musste, um die restlichen zu steuern. Ab dem 10ten Rollladen gab es immer einen Fehler im Log, irgendwas mit Payload..., mal sehen wie sich das jetzt verhält.

                                  1 Reply Last reply Reply Quote 0
                                  • T
                                    tristan last edited by

                                    Servus!

                                    Ich war die ganze Zeit auf der Fährte meine Somfy und Velux Rollläden mit dem KLF 200 zu steuern und freue mich sehr, dass ich hier jetzt noch eine Alternative gefunden habe!

                                    Was mir noch nicht ganz klar ist:

                                    • Welche Hardware brauche ich bzw. welche eignet sich?
                                    • Wie sind die Aussichten irgendwann ohne Cloud auszukommen?

                                    Grüße!

                                    integer63 1 Reply Last reply Reply Quote 0
                                    • integer63
                                      integer63 @tristan last edited by

                                      @tristan sagte in Anfrage Tahoma/Somfy IO Adapter:

                                      KLF 200

                                      Hallo tristan, so wie ich den KLF 200 verstehe, kann man damit nur rudimentär steuern: "Einfache Auf-Stopp-Zu-Ansteuerung von 5 Produkten oder 5 Produktgruppen ... 5 potentialfreie Eingänge sind frei belegbar"

                                      Für den ioBroker Adapter brauchst du entweder eine Tahoma oder eine Connexoon von Somfy - leider alles über Cloud. Aber damit kannst du dann jeden Rollladen/Markise beliebig ansteuern und sehr genau die gewünschte Position anfahren. Also ich bin begeistert (merkt man so gar nicht, oder 😉
                                      )

                                      T 1 Reply Last reply Reply Quote 0
                                      • T
                                        tristan @integer63 last edited by

                                        @integer63 said in Anfrage Tahoma/Somfy IO Adapter:

                                        Für den ioBroker Adapter brauchst du entweder eine Tahoma oder eine Connexoon von Somfy - leider alles über Cloud. Aber damit kannst du dann jeden Rollladen/Markise beliebig ansteuern und sehr genau die gewünschte Position anfahren. Also ich bin begeistert (merkt man so gar nicht, oder 😉

                                        Danke integer63!

                                        Gabs denn bei anderen Cloud-Produkten schon den Ansatz die Cloud lokal zu simulieren, indem Anfragen nach draußen umgeleitet und beantwortet werden?

                                        integer63 StrathCole 2 Replies Last reply Reply Quote 0
                                        • integer63
                                          integer63 @tristan last edited by

                                          @tristan Tut mir leid, aber ich bin kein Entwickler, sondern nur ambitionierter Anwender und kann zu diesem speziellen Thema leider nichts beitragen.

                                          1 Reply Last reply Reply Quote 0
                                          • StrathCole
                                            StrathCole @tristan last edited by

                                            @tristan bei bestimmten Produkten mit sehr einfacher API gab es das (zB Sonoff). Bei Tahoma dürfte das sehr schwierig sein, denn die Box kommuniziert wohl nicht nur via http(s), sondern auch mit UDP-Paketen. Das alles herauszufinden und lokal nachzubilden dürfte eine Herkulesaufgabe sein.

                                            T 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

                                            822
                                            Online

                                            31.9k
                                            Users

                                            80.1k
                                            Topics

                                            1.3m
                                            Posts

                                            102
                                            605
                                            155959
                                            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