Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. ioBroker Allgemein
  4. IoBroker mit Warema WMS Web Control

NEWS

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

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

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

IoBroker mit Warema WMS Web Control

Geplant Angeheftet Gesperrt Verschoben ioBroker Allgemein
127 Beiträge 26 Kommentatoren 39.1k Aufrufe 18 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • W Offline
    W Offline
    willjoha
    schrieb am zuletzt editiert von
    #28

    Bin in den letzten Tagen auch nicht zu viel gekommen. Wollte noch die Messwerte der Wetterstation mit dem Handsender überprüfen allerdings war der Wind nie Stark genug und ich immer zu Spät um die Lumen noch ordentlich zu prüfen…

    Ansonsten verstehe ich mittlerweile ein paar Byte der Control Response.

    Hast du in deinem Script meine Klasse verwendet oder etwas eigenes geschrieben?

    Zum Thema Kanäle: Da bin ich mir ziemlich sicher das diese nur im Handsender bzw WebControl existieren. Wenn der Handsender an einen Kanal mit 4 Aktoren einen Befehl schickt leuchtet die sende LED genau 4 mal. Bei einem WebControl Kanal mit 2 Aktoren hab ich da entsprechend dann auch 2 Nachrichten an die einzelnen Aktoren mit dem ConBee mit geschnitten. Um ganz sicher zu sein könnten wir einem Handsender beim einlernen des Sticks mal vorgaukeln der Stick sei ein Zwischenstecker. Dann könnten wir den Stick im Handsender einem Kanal zuordnen. Bin mir ziemlich sicher das der Stick in diesem Fall nicht mitgeteilt bekommt auf welchen Kanal er programmiert wurde.

    1 Antwort Letzte Antwort
    0
    • P Offline
      P Offline
      Pman
      schrieb am zuletzt editiert von
      #29

      Das mit den Kanälen klingt plausibel. Ich denke mittlerweile, der Windwert funktioniert wie von die beschrieben, bei Temperatur kommt meine Formel zumindest ungefähr hin. Es könnte natürlich eine richtigere Formel (mit sehr ähnlichen) Ergebnissen geben.

      Ich habe für das Skript zum testen einfach die Funktionen zusammengewüftelt, müsste aber leicht auf deine Klasse übertragbar sein bzw. die relevanten Funktionen einfach in eine Klasse übertragbar sein. Ich poste das Skript dir hier einfach mal.

      Die Funktionalität steckt im Prinzip komplett in processWMS, wo auf die ankommenden Packete entsprechend reagiert wird. In dieser Funktion wird dann natürlich auch massiv gebrauch von der ioBroker-API gemacht, also Datenpunkte erstellt und verändert usw..

      Verwendung des Skripts:

      Mit den default-Werten für PANID und KEY müsste sich das Skript im Anlernmodus befinden, kann also über Handsender eingelernt werden, KEY und PANID werden dabei im log ausgegeben.

      Sobald PANID und KEY im Skript hinterlegt werden, wird der Stick damit versorgt und fragt beim Start (und in regelmäßigen Abständen) Raffstore und Wetterstationen ab, speichert die Werte in Datenpunkten und reagiert umgekehrt auf Änderungen in den Datenpunkten 'level' und 'angle'.

      var namespace = 'WMS';
      var SerialPort = require('serialport');
      
      //config
      const PATH = "/dev/ttyUSB0";
      const CHANNEL = 17;
      const PANID = "FFFF"; //inclusion mode: FFFF
      const KEY = "00112233445566778899AABBCCDDEEFF"; //inclusion mode: "00112233445566778899AABBCCDDEEFF"
      var positionInterval = 60; //how often current position is requested (seconds)
      var scanInterval = 600;  //how often to scan for devices (seconds)
      //listPorts();  //uncomment to list all available serial ports
      
      /* do not edit below! */
      //globals
      var knownDevices = {}; //stores known devices
      var lastData = ''; //contains last packet
      var writeQueue = []; //stores data to be sent to serial port
      var timers = {};
      
      /* open serial port and setup parser */
      function init() {
          //scan 3 times
          setTimeout(function () {
              wmsScan();
          }, 5000);
          setTimeout(function () {
              wmsScan();
          }, 10000);
          setTimeout(function () {
              wmsScan();
          }, 30000);
          //scan again every scanInterval seconds
          setInterval(function () {
              wmsScan();
          }, scanInterval * 1000);
      }
      
      //connect to serial port
      const port = new SerialPort(PATH, {
          baudRate: 125000,
          parity: 'none',
          dataBits: 8,
          stopBits: 1,
          autoOpen: false,
      });
      //create parser with '}' as delemiter
      const parser = port.pipe(new SerialPort.parsers.Readline({delimiter: '}'}));
      
      // handle serial port errors
      port.on('error', function () {
          log('serial port error!', 'warn');
          closePort();
      });
      
      //parse incomming packets
      parser.on('data', parseData);
      
      //open serial port
      portOpen().then((msg) => {
          log(msg);
          writeAndWaitFor('{G}', 'gWMS USB-Stick', true).then((line) => {
              return writeAndWaitFor('{V}', 'v', true);
          }).then((line) => {
              log('Stick Version: ' + line);
              return writeAndWaitFor(encodeWMS('setKey', {key: KEY}), 'a', true);
          }).then((line) => {
              return writeAndWaitFor(encodeWMS('switchChannel', {
                  channel: CHANNEL,
                  panId: PANID
              }), 'a', true);
          }).then((line) => {
              init();
          }).catch((err) => {
              log(err, 'warn');
              closePort();
          });
      }).catch((err) => {
          log(err, 'warn');
      });
      
      /* serialport helper functions */
      
      //opens port with promise
      function portOpen() {
          return new Promise((resolve, reject) => {
              port.open((err) => {
                  err ? reject(err) : resolve('port opened');
              })
          });
      }
      
      //close port if open
      function closePort() {
          return new Promise((resolve, reject) => {
              log('closing open serial ports', 'warn');
              if (port && port.isOpen) {
                  // close connection
                  port.close(() => {
                      resolve('port closed')
                  });
              } else {
                  reject('no port was opened');
              }
          });
      }
      
      //on script stop close port
      onStop(closePort, 2000);
      
      //handle incomming data
      function parseData(data) {
          //trim data
          data = wmsTrim(data);
          //do nothing, if packet is received twice
          if (lastData === data) return
          lastData = data;
          log('received message: ' + data, 'debug');
          //decode data into object
          var obj = decodeWMS(data);
          log(JSON.stringify(obj), 'debug');
          //process object
          processWMS(obj);
      }
      
      //list available serial ports
      function listPorts() {
          SerialPort.list().then((ports) => {
              log('Serial Ports: ' + JSON.stringify(ports));
          }).catch((err) => {
              log('error listing ports: ' + JSON.stringify(err));
          });
      }
      
      //write to serial port and wait for answer
      function writeAndWaitFor(data, expect, rejectOnTimeout, timeout) {
          return new Promise((resolve, reject) => {
              if (isNaN(timeout)) timeout = 5000;
              log('sending ' + data, 'debug');
              listener = (line) => {
                  if (wmsTrim(line).substr(0, expect.length) === expect) {
                      log('received expected answer: ' + expect, 'debug');
                      parser.removeListener('data', listener);
                      resolve(wmsTrim(line));
                  } else {
                      log('received unexpected answer (still waiting): ' + wmsTrim(line).substr(0, expect.length) + '!=' + expect, 'debug');
                  }
              };
              parser.on('data', listener);
              enqueue(data);
              //remove listener after 5 seconds
              setTimeout(() => {
                  parser.removeListener('data', listener);
                  rejectOnTimeout ? reject(expect) : resolve(false);
              }, timeout);
          });
      }
      
      function enqueue(data) {
          if (typeof data === 'string') writeQueue.push(data);
          if (writeQueue.length === 1) {
              port.write(writeQueue.shift());
              port.drain((err) => {
                  if (writeQueue.length) enqueue();
              });
          }
      }
      
      /* WMS helper functions */
      
      //trim wms string
      function wmsTrim(data) {
          return data.trim().substr(1);
      }
      
      //decode wms strings into an object
      function decodeWMS(packet) {
          var obj = {};
          switch (packet.substr(0, 1)) {
              case 'g':
                  obj.type = 'stickType';
                  obj.payload = {name: packet.substr(1)};
                  break;
              case 'v':
                  obj.type = 'stickVersion';
                  obj.payload = {version: packet.substr(1)};
                  break;
              case 'f':
                  obj.type = 'error';
                  break;
              case 'a':
                  obj.type = 'ack';
                  break;
              case 'r':
                  obj.type = 'message';
                  obj.payload = decodeWMSMessage(packet.substr(1));
                  break;
              default:
                  obj.type = 'unknown';
                  obj.payload = packet.substr(1);
          }
          return obj;
      }
      
      //decode wms messages into an object
      function decodeWMSMessage(message) {
          var obj = {};
          obj.src = message.substr(0, 6);
          var type = message.substr(6, 4);
          var payload = message.substr(10);
          switch (type) {
              case '5018':
                  obj.type = 'joinNetworkRequest';
                  obj.messagePayload = {
                      panId: payload.substr(0, 4),
                      networkKey: payload.substr(4, 32).match(/../g).reverse().join(""),
                      unknown: payload.substr(36, 2),
                      channel: parseInt(payload.substr(38, 2), 16)
                  };
                  break;
              case '5060':
                  obj.type = 'switchChannelRequest';
                  obj.messagePayload = {
                      panId: payload.substr(0, 4),
                      deviceType: payload.substr(4, 2),
                      channel: parseInt(payload.substr(6, 2), 16)
                  };
                  break;
              case '50AC':
                  obj.type = 'ack';
                  obj.messagePayload = {
                      unknown: payload.substr(0, 4)
                  };
                  break;
              case '7020':
                  obj.type = 'scanRequest';
                  obj.messagePayload = {
                      panId: payload.substr(0, 4),
                      deviceType: payload.substr(4, 2)
                  };
                  break;
              case '7021':
                  obj.type = 'scanResponse';
                  obj.messagePayload = {
                      panId: payload.substr(0, 4),
                      deviceType: payload.substr(4, 2), //63: wetterstation, 06: webcontrol, 02: stick/software, 20: zwischenstecker
                      unknown: payload.substr(6) //optional
                  };
                  break;
              case '7080':
                  obj.type = 'weatherBroadcast';
                  obj.messagePayload = {
                      unknown_1: payload.substr(0, 2),
                      wind: parseInt(payload.substr(2, 2), 16),
                      lumen: payload.substr(4, 2) === '00' ? parseInt(payload.substr(12, 2), 16) * 2 : parseInt(payload.substr(4, 2), 16) * parseInt(payload.substr(12, 2), 16) * 2,
                      unknown_2: payload.substr(6, 6),
                      unknown_3: payload.substr(14, 2),
                      rain: payload.substr(16, 2) === 'C8',
                      temp: parseInt(payload.substr(18, 2), 16) / 2 - 35,
                      unknown_4: payload.substr(20)
                  };
                  break;
              case '7050':
                  obj.type = 'beckonRequest';
                  break;
              case '7070':
                  obj.type = 'controlRequest';
                  obj.messagePayload = {
                      unknown: payload.substr(0, 2),
                      position: parseInt(payload.substr(2, 2), 16) / 2,
                      angle: parseInt(payload.substr(4, 2), 16) - 127,
                      valance_1: payload.substr(6, 2),
                      valance_2: payload.substr(8, 2)
                  };
                  break;
              case '7071':
                  obj.type = 'controlResponse';
                  obj.messagePayload = payload;
                  break;
              case '8010':
                  obj.type = 'parameterGetRequest';
                  obj.messagePayload = {
                      parameter: payload.substr(0) //01000005: position, 26000046: clock timer settings, 0C000006: auto modes & limits
                  };
                  break;
              case '8011':
                  obj.type = 'parameterGetResponse';
                  obj.messagePayload = {
                      parameter: payload.substr(0, 8)
                  };
                  switch (obj.messagePayload.parameter) {
                      case '01000003': //position
                      case '01000005': //position
                          obj.messagePayload.type = 'position';
                          obj.messagePayload.position = parseInt(payload.substr(8, 2), 16) / 2;
                          obj.messagePayload.angle = parseInt(payload.substr(10, 2), 16) - 127;
                          obj.messagePayload.valance_1 = payload.substr(12, 2);
                          obj.messagePayload.valance_2 = payload.substr(14, 2);
                          break;
                      case '0C000006': //auto modes & limits
                          obj.messagePayload.type = 'autoSettings';
                          obj.messagePayload.wind = parseInt(payload.substr(8, 2), 16);
                          obj.messagePayload.rain = parseInt(payload.substr(10, 2), 16);
                          obj.messagePayload.sun = parseInt(payload.substr(12, 2), 16);
                          obj.messagePayload.dusk = parseInt(payload.substr(14, 2), 16);
                          obj.messagePayload.op = parseInt(payload.substr(16, 2), 16);
                          break;
                      case '26000046':
                          obj.messagePayload.type = 'clock';
                          obj.messagePayload.unknown = payload.substr(8);
                          break;
                      default:
                          obj.messagePayload.type = 'unknown';
                          obj.messagePayload.unknown = payload.substr(8);
                  }
                  break;
              case '8020':
                  obj.type = 'parameterSetRequest';
                  obj.messagePayload = {
                      parameter: payload.substr(0, 8)
                  };
                  switch (obj.messagePayload.parameter) {
                      case '0B080009':
                          obj.messagePayload.type = 'clock';
                          obj.messagePayload.year = parseInt(payload.substr(8, 2), 16);
                          obj.messagePayload.month = parseInt(payload.substr(10, 2), 16);
                          obj.messagePayload.day = parseInt(payload.substr(12, 2), 16);
                          obj.messagePayload.hour = parseInt(payload.substr(14, 2), 16);
                          obj.messagePayload.minute = parseInt(payload.substr(16, 2), 16);
                          obj.messagePayload.second = parseInt(payload.substr(18, 2), 16);
                          obj.messagePayload.day_of_week = parseInt(payload.substr(20, 2), 16);
                          obj.messagePayload.unknown = payload.substr(22);
                          break;
                      default:
                          obj.messagePayload.type = 'unknown';
                          obj.messagePayload.unknown = payload.substr(8);
                  }
                  break;
              default:
                  obj.type = 'unknown';
                  obj.messagePayload = payload;
          }
          return obj;
      }
      
      //create wms strings
      function encodeWMS(type, parameter) {
          if (!parameter) parameter = {};
          switch (type) {
              case 'setKey':
                  if (!parameter.key) return false;
                  return '{K401' + parameter.key + '}';
                  break;
              case 'setScanMode':
                  if (isNaN(parameter.channel) || !parameter.panId) return false;
                  return '{M#' + parameter.channel + parameter.panId.match(/../g).reverse().join("") + '}';
                  break;
              case 'switchChannel':
                  if (isNaN(parameter.channel) || !parameter.panId) return false;
                  return '{M%' + parameter.channel + parameter.panId + '}';
                  break;
              case 'ack':
                  if (!parameter.dst) return false;
                  return '{R21' + parameter.dst + '50AC}';
                  break;
              case 'switchChannelRequest': //channel 17 fixed
                  if (!parameter.panId) return false;
                  return '{R04FFFFFF5060' + parameter.panId + '021100}'; // dst or FFFFFF???
                  break;
              case 'scanRequest':
                  return '{R04FFFFFF7020' + parameter.panId + '02}';
                  break;
              case 'scanResponse':
                  if (!parameter.panId || !parameter.dst) return false;
                  return '{R01' + parameter.dst + '7021' + parameter.panId + '02}'; //fixed to deviceType 02 for now
                  break;
              case 'beckonRequest':
                  if (!parameter.dst) return false;
                  return '{R06' + parameter.dst + '7050}';
                  break;
              case 'controlRequest':
                  if (!parameter.dst || isNaN(parameter.position) || isNaN(parameter.angle)) return false;
                  return '{R06' + parameter.dst + '7070' + '03'
                      + ('0' + (Math.min(Math.max(parameter.position, 0), 100) * 2).toString(16)).substr(-2).toUpperCase()
                      + ('0' + (Math.min(Math.max(parameter.angle, 0), 90) + 127).toString(16)).substr(-2).toUpperCase()
                      + 'FFFF}'; //no idea how valance works
                  break;
              case 'parameterGetRequest':
                  if (!parameter.dst || !parameter.parameter) return false;
                  return '{R06' + parameter.dst + '8010' + parameter.parameter + '}';
                  break;
              case 'parameterGetRequestPosition':
                  if (!parameter.dst) return false;
                  return '{R06' + parameter.dst + '8010' + '01000005}';
                  break;
              case 'parameterGetRequestClock':
                  if (!parameter.dst) return false;
                  return '{R06' + parameter.dst + '8010' + '26000046}';
                  break;
              case 'parameterGetRequestAutoSettings':
                  if (!parameter.dst) return false;
                  return '{R06' + parameter.dst + '8010' + '0C000006}';
                  break;
              case 'parameterSetRequestAutoSettings':
                  if (!parameter.dst || !parameter.parameter
                      || isNaN(parameter.wind) || isNaN(parameter.rain)
                      || isNaN(parameter.sun) || isNaN(parameter.dusk))
                      return false;
                  return '{R06' + parameter.dst + '8020' + '0D000004'
                      + ('0' + Math.min(Math.max(parameter.wind, 0), 9).toString(16)).substr(-2).toUpperCase()
                      + ('0' + Math.min(Math.max(parameter.rain, 0), 9).toString(16)).substr(-2).toUpperCase()
                      + ('0' + Math.min(Math.max(parameter.sun, 0), 9).toString(16)).substr(-2).toUpperCase()
                      + ('0' + Math.min(Math.max(parameter.dusk, 0), 9).toString(16)).substr(-2).toUpperCase()
                      + (parameter.op ? '01' : '00')
                      + '}';
                  break;
              case 'parameterSetRequestAutoAll':
                  if (!parameter.dst) return false;
                  return '{R06' + parameter.dst + '8020' + '0D040001' + (parameter.op ? '01' : '00') + '}';
                  break;
              default: //unkown message type
                  return false;
                  break;
          }
      }
      
      //process packets
      function processWMS(obj) {
          //log(JSON.stringify(obj));
          if (obj.type !== 'message') return;
          switch (obj.payload.type) {
              case 'switchChannelRequest':
                  log('received switchChannelRequest, switching channel to ' + obj.payload.messagePayload.channel, 'debug');
                  writeAndWaitFor(encodeWMS('switchChannel', {
                      channel: obj.payload.messagePayload.channel,
                      panId: PANID
                  }), 'a');
                  break;
              case 'scanRequest':
                  // send scanResponse
                  log('received scanRequest, sending scanResponse', 'debug');
                  writeAndWaitFor(encodeWMS('scanResponse', {dst: obj.payload.src, panId: PANID}), 'a');
                  break;
              case 'joinNetworkRequest':
                  log('received joinNetworkRequest:', 'debug');
                  log('KEY: ' + obj.payload.messagePayload.networkKey);
                  log('CHANNEL: ' + obj.payload.messagePayload.channel);
                  log('PANID: ' + obj.payload.messagePayload.panId);
                  writeAndWaitFor(encodeWMS('ack', {dst: obj.payload.src}), 'a');
                  break;
              case 'scanResponse':
                  log('received scanResponse', 'debug');
                  log('TYPE: ' + obj.payload.messagePayload.deviceType, 'debug');
                  log('SNR:' + obj.payload.src, 'debug');
                  if (obj.payload.messagePayload.deviceType === '20') {
                      createState(this.namespace + '.Raffstore.' + obj.payload.src + '.position', 0, false, {
                          type: 'number',
                          min: 0,
                          max: 100,
                          unit: '%'
                      });
                      createState(this.namespace + '.Raffstore.' + obj.payload.src + '.angle', 0, false, {
                          type: 'number',
                          min: 0,
                          max: 90,
                          unit: '°'
                      }, function () {
                          if (knownDevices[obj.payload.src]) return;
                          knownDevices[obj.payload.src] = true;
                          var src = obj.payload.src;
                          log('device type 20 found: ' + src);
                          var deviceId = 'javascript.' + instance + '.' + this.namespace + '.Raffstore.' + src;
                          on({id: deviceId + '.position', change: 'ne', ack: false}, function (obj) {
                              //send parameter
                              writeAndWaitFor(
                                  encodeWMS('controlRequest', {
                                      dst: src,
                                      position: obj.state.val,
                                      angle: getState(deviceId + '.angle').val
                                  }),
                                  'r' + src + '7071'
                              ).then(() => {
                                  var lastValue = getState(deviceId + '.position').val;
                                  writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                  var timer = setInterval(function () {
                                      //get parameter periodicaly until no change is detected
                                      log(getState(deviceId + '.position').val + ':' + lastValue, 'debug')
                                      if (getState(deviceId + '.position').val === lastValue)
                                          clearInterval(timer);
                                      lastValue = getState(deviceId + '.position').val;
                                      writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                  },  3500);
                                  //setState(deviceId + '.position', getState(deviceId + '.position').val, true);
                              });
                          });
                          on({id: deviceId + '.angle', change: 'ne', ack: false}, function (obj) {
                              //send parameter
                              writeAndWaitFor(encodeWMS('controlRequest', {
                                      dst: src,
                                      position: getState(deviceId + '.position').val,
                                      angle: obj.state.val
                                  }),
                                  'r' + src + '7071'
                              ).then(() => {
                                  var lastValue = getState(deviceId + '.angle').val;
                                  writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                  var timer = setInterval(function () {
                                      //get parameter periodicaly until no change is detected
                                      log(getState(deviceId + '.angle').val + ':' + lastValue, 'debug')
                                      if (getState(deviceId + '.angle').val === lastValue)
                                          clearInterval(timer);
                                      lastValue = getState(deviceId + '.angle').val;
                                      writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                  },  3500);
                                  //setState(deviceId + '.angle', getState(deviceId + '.angle').val, true);
                              });
                          });
                          setTimeout(function () {
                              //get parameter once
                              writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                          }, 5000 + Math.random() * 5000);
                          setInterval(function () {
                              //get parameter periodicaly
                              writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                          }, positionInterval * 1000 + Math.random() * 5000);
                      });
                  }
                  break;
              case 'parameterGetResponse':
                  log('received parameterGetResponse', 'debug');
                  switch (obj.payload.messagePayload.type) {
                      case 'position':
                          setStateDelayed(this.namespace + '.Raffstore.' + obj.payload.src + '.position', obj.payload.messagePayload.position, true, 100, true);
                          setStateDelayed(this.namespace + '.Raffstore.' + obj.payload.src + '.angle', obj.payload.messagePayload.angle, true, 100, true);
                      default:
                          break;
                  }
                  break;
              case 'weatherBroadcast':
                  log('received weatherBroadcast', 'debug');
                  createState(this.namespace + '.Wetter.' + obj.payload.src + '.temp', 0, false, {
                      type: 'number',
                      unit: '°C',
                      write: false
                  }, function () {
                      setStateDelayed(this.namespace + '.Wetter.' + obj.payload.src + '.temp', obj.payload.messagePayload.temp, true, 100, true);
                  });
                  createState(this.namespace + '.Wetter.' + obj.payload.src + '.wind', 0, false, {
                      type: 'number',
                      min: 0,
                      unit: 'm/s',
                      write: false
                  }, function () {
                      setStateDelayed(this.namespace + '.Wetter.' + obj.payload.src + '.wind', obj.payload.messagePayload.wind, true, 100, true);
                  });
                  createState(this.namespace + '.Wetter.' + obj.payload.src + '.lux', 0, false, {
                      type: 'number',
                      min: 0,
                      unit: 'lux',
                      write: false
                  }, function () {
                      setStateDelayed(this.namespace + '.Wetter.' + obj.payload.src + '.lux', obj.payload.messagePayload.lumen, true, 100, true);
                  });
                  createState(this.namespace + '.Wetter.' + obj.payload.src + '.rain', false, false, {
                      type: 'boolean',
                      write: false
                  }, function () {
                      setStateDelayed(this.namespace + '.Wetter.' + obj.payload.src + '.rain', obj.payload.messagePayload.rain, true, 100, true);
                  });
                  break;
              default:
                  break;
          }
      }
      
      //scan for devices
      function wmsScan() {
          writeAndWaitFor(encodeWMS('scanRequest', {panId: PANID}), 'a');
      }
      
      
      1 Antwort Letzte Antwort
      0
      • P Offline
        P Offline
        Pman
        schrieb am zuletzt editiert von
        #30

        Wie sieht es eigtl. mit dem STOP-Befehl aus? Hast du da etwas?

        1 Antwort Letzte Antwort
        0
        • L Offline
          L Offline
          LaBamba
          schrieb am zuletzt editiert von
          #31

          Wirklich schade, dass anscheinend dieses Thema Warema Raffstoresteuerung nicht mehr weiterverfolgt wird und ein offizieller Adapter für den ioBroker geschaffen wird. Leider habe ich wenig Ahnung von der Programmierung aber ich kenne mindest 10 Leute die sich auch freuen würden.

          1 Antwort Letzte Antwort
          0
          • R Offline
            R Offline
            radiorichter
            schrieb am zuletzt editiert von
            #32

            @LaBamba:

            Wirklich schade, dass anscheinend dieses Thema Warema Raffstoresteuerung nicht mehr weiterverfolgt wird und ein offizieller Adapter für den ioBroker geschaffen wird. Leider habe ich wenig Ahnung von der Programmierung aber ich kenne mindest 10 Leute die sich auch freuen würden. ` Geht mir leider genau so. Wäre auch dazu bereit mitzuhelfen wo ich nur kann ;) oder auch Spenden wenn's sein muss :)

            Gesendet von meinem HUAWEI VNS-L21 mit Tapatalk

            1 Antwort Letzte Antwort
            0
            • P Offline
              P Offline
              Pman
              schrieb am zuletzt editiert von
              #33

              Leider keine Zeit, das Skript ist aber so lauffähig!

              1 Antwort Letzte Antwort
              0
              • R Offline
                R Offline
                radiorichter
                schrieb am zuletzt editiert von
                #34

                kein Thema, aber auf jeden Fall vielen Dank für das Skript. Bei mir wird es erst im Sommer soweit sein, wird dann schon klappen ;)

                1 Antwort Letzte Antwort
                0
                • L Offline
                  L Offline
                  LaBamba
                  schrieb am zuletzt editiert von
                  #35

                  Pman trotzdem super, dass du es so weit schon geschrieben hast. Vielleicht findet sich ja ein anderer der die Fähigkeiten hat dieses Skript in einen Adapter umzusetzen. Würde mich mega freuen!

                  1 Antwort Letzte Antwort
                  0
                  • P Offline
                    P Offline
                    Pman
                    schrieb am zuletzt editiert von
                    #36

                    @LaBamba:

                    Pman trotzdem super, dass du es so weit schon geschrieben hast. Vielleicht findet sich ja ein anderer der die Fähigkeiten hat dieses Skript in einen Adapter umzusetzen. Würde mich mega freuen! `
                    Adapter wäre natürlich super und bequem, aber unterm Strich hast du genau das gleiche mit dem Skript, was ein Adapter machen würde. Also keine falsche Scheu! Wenn das Skript jemand nutzen möchte helfe ich gerne bei der Ersteinrichtung, falls es Probleme gibt.

                    1 Antwort Letzte Antwort
                    0
                    • R Offline
                      R Offline
                      radiorichter
                      schrieb am zuletzt editiert von
                      #37

                      Pman, wärst du so nett und würdest uns einfach kurz zusammenfassen was man genau machen muss? Eine ganz kleine step by step Anleitung. Das ich beide scripte brauche, hab ich bereits verstanden, aber diese einfach in den iobroker reinpacken wird ja nicht reichen oder?

                      Eilt bei mir eh nicht wirklich, aber dafür wär ich / wir dir mega dankbar :D

                      1 Antwort Letzte Antwort
                      0
                      • P Offline
                        P Offline
                        Pman
                        schrieb am zuletzt editiert von
                        #38

                        Du benötigst den Javascript-Adapter und einen WMS-Stick.

                        Kurze Anleitung:

                        1. Falls nicht vorhanden den Javascript-Adapter installieren

                        2. Im Javascript Adapter bei "zusätzliche NPM-Module" "serialport" eintragen, dann sollte der Adapter neu starten und das serialport-Packet installieren, was ggf. etwas dauert.

                        3. Im Admin im Skripte-Tab Ein neues Skript (Javascript!) erstellen und das unten angefügte Skript einfügen, dabei die "//" vor "listPorts();" weg machen, damit beim ersten Start des Skripts die Seriellen Ports im LOG aufgelistet werden. Das Skript nun starten. Im Normalfall sollte der WMS-Stick auf einem Raspi wie bei mir unter /dev/ttyUSB0 zu finden sein, ansonsten muss man dies anpassen im Skript. Nachdem der Pfad zum WMS-Stick bekannt ist und eingetragen wurde "listPorts();" wieder auskommentieren. Das Skript neustarten.

                        4. CHANNEL, PANID und KEY müssen nun bestimmt werden, dazu ist eine WMS-Zentrale oder WMS-Fernbedienung nötig. Einfach wie in der jeweiligen Anleitung beschrieben ein neues Gerät in das Netzwerk aufnehmen, dabei sollte der WMS-Stick gefunden werden. Sobald man diesen in das Netzwerk aufnimmt werden im LOG des Skriptes die drei Werte angezeigt.

                        5. CHANNEL, PANID und KEY in das Skript eintrage und Skript neustarten.

                        6. Unter javascript.0.WMS sollten nun für alle gefunden Geräte (Motoren, Wetterstationen usw.) Datenpunkte angelegt werden, die Nutzung sollte halbwegs selbsterlärend sein (level, angle).

                        var namespace = 'WMS';
                        var SerialPort = require('serialport');
                        
                        //config
                        const PATH = "/dev/ttyUSB0";
                        const CHANNEL = 17;
                        const PANID = "FFFF"; //inclusion mode: FFFF
                        const KEY = "00112233445566778899AABBCCDDEEFF"; //inclusion mode: "00112233445566778899AABBCCDDEEFF"
                        var positionInterval = 60; //how often current position is requested (seconds)
                        var scanInterval = 600;  //how often to scan for devices (seconds)
                        //listPorts();  //uncomment to list all available serial ports
                        
                        /* do not edit below! */
                        //globals
                        var knownDevices = {}; //stores known devices
                        var lastData = ''; //contains last packet
                        var writeQueue = []; //stores data to be sent to serial port
                        var timers = {};
                        
                        /* open serial port and setup parser */
                        function init() {
                            //scan 3 times
                            setTimeout(function () {
                                wmsScan();
                            }, 5000);
                            setTimeout(function () {
                                wmsScan();
                            }, 10000);
                            setTimeout(function () {
                                wmsScan();
                            }, 30000);
                            //scan again every scanInterval seconds
                            setInterval(function () {
                                wmsScan();
                            }, scanInterval * 1000);
                        }
                        
                        //connect to serial port
                        const port = new SerialPort(PATH, {
                            baudRate: 125000,
                            parity: 'none',
                            dataBits: 8,
                            stopBits: 1,
                            autoOpen: false,
                        });
                        //create parser with '}' as delemiter
                        const parser = port.pipe(new SerialPort.parsers.Readline({delimiter: '}'}));
                        
                        // handle serial port errors
                        port.on('error', function () {
                            log('serial port error!', 'warn');
                            closePort();
                        });
                        
                        //parse incomming packets
                        parser.on('data', parseData);
                        
                        //open serial port
                        portOpen().then((msg) => {
                            log(msg);
                            writeAndWaitFor('{G}', 'gWMS USB-Stick', true).then((line) => {
                                return writeAndWaitFor('{V}', 'v', true);
                            }).then((line) => {
                                log('Stick Version: ' + line);
                                return writeAndWaitFor(encodeWMS('setKey', {key: KEY}), 'a', true);
                            }).then((line) => {
                                return writeAndWaitFor(encodeWMS('switchChannel', {
                                    channel: CHANNEL,
                                    panId: PANID
                                }), 'a', true);
                            }).then((line) => {
                                init();
                            }).catch((err) => {
                                log(err, 'warn');
                                closePort();
                            });
                        }).catch((err) => {
                            log(err, 'warn');
                        });
                        
                        /* serialport helper functions */
                        
                        //opens port with promise
                        function portOpen() {
                            return new Promise((resolve, reject) => {
                                port.open((err) => {
                                    err ? reject(err) : resolve('port opened');
                                })
                            });
                        }
                        
                        //close port if open
                        function closePort() {
                            return new Promise((resolve, reject) => {
                                log('closing open serial ports', 'warn');
                                if (port && port.isOpen) {
                                    // close connection
                                    port.close(() => {
                                        resolve('port closed')
                                    });
                                } else {
                                    reject('no port was opened');
                                }
                            });
                        }
                        
                        //on script stop close port
                        onStop(closePort, 2000);
                        
                        //handle incomming data
                        function parseData(data) {
                            //trim data
                            data = wmsTrim(data);
                            //do nothing, if packet is received twice
                            if (lastData === data) return
                            lastData = data;
                            log('received message: ' + data, 'debug');
                            //decode data into object
                            var obj = decodeWMS(data);
                            log(JSON.stringify(obj), 'debug');
                            //process object
                            processWMS(obj);
                        }
                        
                        //list available serial ports
                        function listPorts() {
                            SerialPort.list().then((ports) => {
                                log('Serial Ports: ' + JSON.stringify(ports));
                            }).catch((err) => {
                                log('error listing ports: ' + JSON.stringify(err));
                            });
                        }
                        
                        //write to serial port and wait for answer
                        function writeAndWaitFor(data, expect, rejectOnTimeout, timeout) {
                            return new Promise((resolve, reject) => {
                                if (isNaN(timeout)) timeout = 5000;
                                log('sending ' + data, 'debug');
                                listener = (line) => {
                                    if (wmsTrim(line).substr(0, expect.length) === expect) {
                                        log('received expected answer: ' + expect, 'debug');
                                        parser.removeListener('data', listener);
                                        resolve(wmsTrim(line));
                                    } else {
                                        log('received unexpected answer (still waiting): ' + wmsTrim(line).substr(0, expect.length) + '!=' + expect, 'debug');
                                    }
                                };
                                parser.on('data', listener);
                                enqueue(data);
                                //remove listener after 5 seconds
                                setTimeout(() => {
                                    parser.removeListener('data', listener);
                                    rejectOnTimeout ? reject(expect) : resolve(false);
                                }, timeout);
                            });
                        }
                        
                        function enqueue(data) {
                            if (typeof data === 'string') writeQueue.push(data);
                            if (writeQueue.length === 1) {
                                port.write(writeQueue.shift());
                                port.drain((err) => {
                                    if (writeQueue.length) enqueue();
                                });
                            }
                        }
                        
                        /* WMS helper functions */
                        
                        //trim wms string
                        function wmsTrim(data) {
                            return data.trim().substr(1);
                        }
                        
                        //decode wms strings into an object
                        function decodeWMS(packet) {
                            var obj = {};
                            switch (packet.substr(0, 1)) {
                                case 'g':
                                    obj.type = 'stickType';
                                    obj.payload = {name: packet.substr(1)};
                                    break;
                                case 'v':
                                    obj.type = 'stickVersion';
                                    obj.payload = {version: packet.substr(1)};
                                    break;
                                case 'f':
                                    obj.type = 'error';
                                    break;
                                case 'a':
                                    obj.type = 'ack';
                                    break;
                                case 'r':
                                    obj.type = 'message';
                                    obj.payload = decodeWMSMessage(packet.substr(1));
                                    break;
                                default:
                                    obj.type = 'unknown';
                                    obj.payload = packet.substr(1);
                            }
                            return obj;
                        }
                        
                        //decode wms messages into an object
                        function decodeWMSMessage(message) {
                            var obj = {};
                            obj.src = message.substr(0, 6);
                            var type = message.substr(6, 4);
                            var payload = message.substr(10);
                            switch (type) {
                                case '5018':
                                    obj.type = 'joinNetworkRequest';
                                    obj.messagePayload = {
                                        panId: payload.substr(0, 4),
                                        networkKey: payload.substr(4, 32).match(/../g).reverse().join(""),
                                        unknown: payload.substr(36, 2),
                                        channel: parseInt(payload.substr(38, 2), 16)
                                    };
                                    break;
                                case '5060':
                                    obj.type = 'switchChannelRequest';
                                    obj.messagePayload = {
                                        panId: payload.substr(0, 4),
                                        deviceType: payload.substr(4, 2),
                                        channel: parseInt(payload.substr(6, 2), 16)
                                    };
                                    break;
                                case '50AC':
                                    obj.type = 'ack';
                                    obj.messagePayload = {
                                        unknown: payload.substr(0, 4)
                                    };
                                    break;
                                case '7020':
                                    obj.type = 'scanRequest';
                                    obj.messagePayload = {
                                        panId: payload.substr(0, 4),
                                        deviceType: payload.substr(4, 2)
                                    };
                                    break;
                                case '7021':
                                    obj.type = 'scanResponse';
                                    obj.messagePayload = {
                                        panId: payload.substr(0, 4),
                                        deviceType: payload.substr(4, 2), //63: wetterstation, 06: webcontrol, 02: stick/software, 20: zwischenstecker
                                        unknown: payload.substr(6) //optional
                                    };
                                    break;
                                case '7080':
                                    obj.type = 'weatherBroadcast';
                                    obj.messagePayload = {
                                        unknown_1: payload.substr(0, 2),
                                        wind: parseInt(payload.substr(2, 2), 16),
                                        lumen: payload.substr(4, 2) === '00' ? parseInt(payload.substr(12, 2), 16) * 2 : parseInt(payload.substr(4, 2), 16) * parseInt(payload.substr(12, 2), 16) * 2,
                                        unknown_2: payload.substr(6, 6),
                                        unknown_3: payload.substr(14, 2),
                                        rain: payload.substr(16, 2) === 'C8',
                                        temp: parseInt(payload.substr(18, 2), 16) / 2 - 35,
                                        unknown_4: payload.substr(20)
                                    };
                                    break;
                                case '7050':
                                    obj.type = 'beckonRequest';
                                    break;
                                case '7070':
                                    obj.type = 'controlRequest';
                                    obj.messagePayload = {
                                        unknown: payload.substr(0, 2),
                                        position: parseInt(payload.substr(2, 2), 16) / 2,
                                        angle: parseInt(payload.substr(4, 2), 16) - 127,
                                        valance_1: payload.substr(6, 2),
                                        valance_2: payload.substr(8, 2)
                                    };
                                    break;
                                case '7071':
                                    obj.type = 'controlResponse';
                                    obj.messagePayload = payload;
                                    break;
                                case '8010':
                                    obj.type = 'parameterGetRequest';
                                    obj.messagePayload = {
                                        parameter: payload.substr(0) //01000005: position, 26000046: clock timer settings, 0C000006: auto modes & limits
                                    };
                                    break;
                                case '8011':
                                    obj.type = 'parameterGetResponse';
                                    obj.messagePayload = {
                                        parameter: payload.substr(0, 8)
                                    };
                                    switch (obj.messagePayload.parameter) {
                                        case '01000003': //position
                                        case '01000005': //position
                                            obj.messagePayload.type = 'position';
                                            obj.messagePayload.position = parseInt(payload.substr(8, 2), 16) / 2;
                                            obj.messagePayload.angle = parseInt(payload.substr(10, 2), 16) - 127;
                                            obj.messagePayload.valance_1 = payload.substr(12, 2);
                                            obj.messagePayload.valance_2 = payload.substr(14, 2);
                                            break;
                                        case '0C000006': //auto modes & limits
                                            obj.messagePayload.type = 'autoSettings';
                                            obj.messagePayload.wind = parseInt(payload.substr(8, 2), 16);
                                            obj.messagePayload.rain = parseInt(payload.substr(10, 2), 16);
                                            obj.messagePayload.sun = parseInt(payload.substr(12, 2), 16);
                                            obj.messagePayload.dusk = parseInt(payload.substr(14, 2), 16);
                                            obj.messagePayload.op = parseInt(payload.substr(16, 2), 16);
                                            break;
                                        case '26000046':
                                            obj.messagePayload.type = 'clock';
                                            obj.messagePayload.unknown = payload.substr(8);
                                            break;
                                        default:
                                            obj.messagePayload.type = 'unknown';
                                            obj.messagePayload.unknown = payload.substr(8);
                                    }
                                    break;
                                case '8020':
                                    obj.type = 'parameterSetRequest';
                                    obj.messagePayload = {
                                        parameter: payload.substr(0, 8)
                                    };
                                    switch (obj.messagePayload.parameter) {
                                        case '0B080009':
                                            obj.messagePayload.type = 'clock';
                                            obj.messagePayload.year = parseInt(payload.substr(8, 2), 16);
                                            obj.messagePayload.month = parseInt(payload.substr(10, 2), 16);
                                            obj.messagePayload.day = parseInt(payload.substr(12, 2), 16);
                                            obj.messagePayload.hour = parseInt(payload.substr(14, 2), 16);
                                            obj.messagePayload.minute = parseInt(payload.substr(16, 2), 16);
                                            obj.messagePayload.second = parseInt(payload.substr(18, 2), 16);
                                            obj.messagePayload.day_of_week = parseInt(payload.substr(20, 2), 16);
                                            obj.messagePayload.unknown = payload.substr(22);
                                            break;
                                        default:
                                            obj.messagePayload.type = 'unknown';
                                            obj.messagePayload.unknown = payload.substr(8);
                                    }
                                    break;
                                default:
                                    obj.type = 'unknown';
                                    obj.messagePayload = payload;
                            }
                            return obj;
                        }
                        
                        //create wms strings
                        function encodeWMS(type, parameter) {
                            if (!parameter) parameter = {};
                            switch (type) {
                                case 'setKey':
                                    if (!parameter.key) return false;
                                    return '{K401' + parameter.key + '}';
                                    break;
                                case 'setScanMode':
                                    if (isNaN(parameter.channel) || !parameter.panId) return false;
                                    return '{M#' + parameter.channel + parameter.panId.match(/../g).reverse().join("") + '}';
                                    break;
                                case 'switchChannel':
                                    if (isNaN(parameter.channel) || !parameter.panId) return false;
                                    return '{M%' + parameter.channel + parameter.panId + '}';
                                    break;
                                case 'ack':
                                    if (!parameter.dst) return false;
                                    return '{R21' + parameter.dst + '50AC}';
                                    break;
                                case 'switchChannelRequest': //channel 17 fixed
                                    if (!parameter.panId) return false;
                                    return '{R04FFFFFF5060' + parameter.panId + '021100}'; // dst or FFFFFF???
                                    break;
                                case 'scanRequest':
                                    return '{R04FFFFFF7020' + parameter.panId + '02}';
                                    break;
                                case 'scanResponse':
                                    if (!parameter.panId || !parameter.dst) return false;
                                    return '{R01' + parameter.dst + '7021' + parameter.panId + '02}'; //fixed to deviceType 02 for now
                                    break;
                                case 'beckonRequest':
                                    if (!parameter.dst) return false;
                                    return '{R06' + parameter.dst + '7050}';
                                    break;
                                case 'controlRequest':
                                    if (!parameter.dst || isNaN(parameter.position) || isNaN(parameter.angle)) return false;
                                    return '{R06' + parameter.dst + '7070' + '03'
                                        + ('0' + (Math.min(Math.max(parameter.position, 0), 100) * 2).toString(16)).substr(-2).toUpperCase()
                                        + ('0' + (Math.min(Math.max(parameter.angle, 0), 90) + 127).toString(16)).substr(-2).toUpperCase()
                                        + 'FFFF}'; //no idea how valance works
                                    break;
                                case 'parameterGetRequest':
                                    if (!parameter.dst || !parameter.parameter) return false;
                                    return '{R06' + parameter.dst + '8010' + parameter.parameter + '}';
                                    break;
                                case 'parameterGetRequestPosition':
                                    if (!parameter.dst) return false;
                                    return '{R06' + parameter.dst + '8010' + '01000005}';
                                    break;
                                case 'parameterGetRequestClock':
                                    if (!parameter.dst) return false;
                                    return '{R06' + parameter.dst + '8010' + '26000046}';
                                    break;
                                case 'parameterGetRequestAutoSettings':
                                    if (!parameter.dst) return false;
                                    return '{R06' + parameter.dst + '8010' + '0C000006}';
                                    break;
                                case 'parameterSetRequestAutoSettings':
                                    if (!parameter.dst || !parameter.parameter
                                        || isNaN(parameter.wind) || isNaN(parameter.rain)
                                        || isNaN(parameter.sun) || isNaN(parameter.dusk))
                                        return false;
                                    return '{R06' + parameter.dst + '8020' + '0D000004'
                                        + ('0' + Math.min(Math.max(parameter.wind, 0), 9).toString(16)).substr(-2).toUpperCase()
                                        + ('0' + Math.min(Math.max(parameter.rain, 0), 9).toString(16)).substr(-2).toUpperCase()
                                        + ('0' + Math.min(Math.max(parameter.sun, 0), 9).toString(16)).substr(-2).toUpperCase()
                                        + ('0' + Math.min(Math.max(parameter.dusk, 0), 9).toString(16)).substr(-2).toUpperCase()
                                        + (parameter.op ? '01' : '00')
                                        + '}';
                                    break;
                                case 'parameterSetRequestAutoAll':
                                    if (!parameter.dst) return false;
                                    return '{R06' + parameter.dst + '8020' + '0D040001' + (parameter.op ? '01' : '00') + '}';
                                    break;
                                default: //unkown message type
                                    return false;
                                    break;
                            }
                        }
                        
                        //process packets
                        function processWMS(obj) {
                            //log(JSON.stringify(obj));
                            if (obj.type !== 'message') return;
                            switch (obj.payload.type) {
                                case 'switchChannelRequest':
                                    log('received switchChannelRequest, switching channel to ' + obj.payload.messagePayload.channel, 'debug');
                                    writeAndWaitFor(encodeWMS('switchChannel', {
                                        channel: obj.payload.messagePayload.channel,
                                        panId: PANID
                                    }), 'a');
                                    break;
                                case 'scanRequest':
                                    // send scanResponse
                                    log('received scanRequest, sending scanResponse', 'debug');
                                    writeAndWaitFor(encodeWMS('scanResponse', {dst: obj.payload.src, panId: PANID}), 'a');
                                    break;
                                case 'joinNetworkRequest':
                                    log('received joinNetworkRequest:', 'debug');
                                    log('KEY: ' + obj.payload.messagePayload.networkKey);
                                    log('CHANNEL: ' + obj.payload.messagePayload.channel);
                                    log('PANID: ' + obj.payload.messagePayload.panId);
                                    writeAndWaitFor(encodeWMS('ack', {dst: obj.payload.src}), 'a');
                                    break;
                                case 'scanResponse':
                                    log('received scanResponse', 'debug');
                                    log('TYPE: ' + obj.payload.messagePayload.deviceType, 'debug');
                                    log('SNR:' + obj.payload.src, 'debug');
                                    if (obj.payload.messagePayload.deviceType === '20') {
                                        createState(this.namespace + '.Raffstore.' + obj.payload.src + '.position', 0, false, {
                                            type: 'number',
                                            min: 0,
                                            max: 100,
                                            unit: '%'
                                        });
                                        createState(this.namespace + '.Raffstore.' + obj.payload.src + '.angle', 0, false, {
                                            type: 'number',
                                            min: 0,
                                            max: 90,
                                            unit: '°'
                                        }, function () {
                                            if (knownDevices[obj.payload.src]) return;
                                            knownDevices[obj.payload.src] = true;
                                            var src = obj.payload.src;
                                            log('device type 20 found: ' + src);
                                            var deviceId = 'javascript.' + instance + '.' + this.namespace + '.Raffstore.' + src;
                                            on({id: deviceId + '.position', change: 'ne', ack: false}, function (obj) {
                                                //send parameter
                                                writeAndWaitFor(
                                                    encodeWMS('controlRequest', {
                                                        dst: src,
                                                        position: obj.state.val,
                                                        angle: getState(deviceId + '.angle').val
                                                    }),
                                                    'r' + src + '7071'
                                                ).then(() => {
                                                    var lastValue = getState(deviceId + '.position').val;
                                                    writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                                    var timer = setInterval(function () {
                                                        //get parameter periodicaly until no change is detected
                                                        log(getState(deviceId + '.position').val + ':' + lastValue, 'debug')
                                                        if (getState(deviceId + '.position').val === lastValue)
                                                            clearInterval(timer);
                                                        lastValue = getState(deviceId + '.position').val;
                                                        writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                                    },  3500);
                                                    //setState(deviceId + '.position', getState(deviceId + '.position').val, true);
                                                });
                                            });
                                            on({id: deviceId + '.angle', change: 'ne', ack: false}, function (obj) {
                                                //send parameter
                                                writeAndWaitFor(encodeWMS('controlRequest', {
                                                        dst: src,
                                                        position: getState(deviceId + '.position').val,
                                                        angle: obj.state.val
                                                    }),
                                                    'r' + src + '7071'
                                                ).then(() => {
                                                    var lastValue = getState(deviceId + '.angle').val;
                                                    writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                                    var timer = setInterval(function () {
                                                        //get parameter periodicaly until no change is detected
                                                        log(getState(deviceId + '.angle').val + ':' + lastValue, 'debug')
                                                        if (getState(deviceId + '.angle').val === lastValue)
                                                            clearInterval(timer);
                                                        lastValue = getState(deviceId + '.angle').val;
                                                        writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                                    },  3500);
                                                    //setState(deviceId + '.angle', getState(deviceId + '.angle').val, true);
                                                });
                                            });
                                            setTimeout(function () {
                                                //get parameter once
                                                writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                            }, 5000 + Math.random() * 5000);
                                            setInterval(function () {
                                                //get parameter periodicaly
                                                writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                            }, positionInterval * 1000 + Math.random() * 5000);
                                        });
                                    }
                                    break;
                                case 'parameterGetResponse':
                                    log('received parameterGetResponse', 'debug');
                                    switch (obj.payload.messagePayload.type) {
                                        case 'position':
                                            setStateDelayed(this.namespace + '.Raffstore.' + obj.payload.src + '.position', obj.payload.messagePayload.position, true, 100, true);
                                            setStateDelayed(this.namespace + '.Raffstore.' + obj.payload.src + '.angle', obj.payload.messagePayload.angle, true, 100, true);
                                        default:
                                            break;
                                    }
                                    break;
                                case 'weatherBroadcast':
                                    log('received weatherBroadcast', 'debug');
                                    createState(this.namespace + '.Wetter.' + obj.payload.src + '.temp', 0, false, {
                                        type: 'number',
                                        unit: '°C',
                                        write: false
                                    }, function () {
                                        setStateDelayed(this.namespace + '.Wetter.' + obj.payload.src + '.temp', obj.payload.messagePayload.temp, true, 100, true);
                                    });
                                    createState(this.namespace + '.Wetter.' + obj.payload.src + '.wind', 0, false, {
                                        type: 'number',
                                        min: 0,
                                        unit: 'm/s',
                                        write: false
                                    }, function () {
                                        setStateDelayed(this.namespace + '.Wetter.' + obj.payload.src + '.wind', obj.payload.messagePayload.wind, true, 100, true);
                                    });
                                    createState(this.namespace + '.Wetter.' + obj.payload.src + '.lux', 0, false, {
                                        type: 'number',
                                        min: 0,
                                        unit: 'lux',
                                        write: false
                                    }, function () {
                                        setStateDelayed(this.namespace + '.Wetter.' + obj.payload.src + '.lux', obj.payload.messagePayload.lumen, true, 100, true);
                                    });
                                    createState(this.namespace + '.Wetter.' + obj.payload.src + '.rain', false, false, {
                                        type: 'boolean',
                                        write: false
                                    }, function () {
                                        setStateDelayed(this.namespace + '.Wetter.' + obj.payload.src + '.rain', obj.payload.messagePayload.rain, true, 100, true);
                                    });
                                    break;
                                default:
                                    break;
                            }
                        }
                        
                        //scan for devices
                        function wmsScan() {
                            writeAndWaitFor(encodeWMS('scanRequest', {panId: PANID}), 'a');
                        }
                        
                        
                        1 Antwort Letzte Antwort
                        0
                        • E Offline
                          E Offline
                          Eberhart
                          schrieb am zuletzt editiert von
                          #39

                          @Pman:

                          … `

                          Wow.Hammer, was du hier abgeliefert hast. Vielen lieben Dank dafür. Ich hab mich schon eine Weile lang geärgert, dass ich auf das proprietäre WMS gesetzt habe. Nun habe ich aber keinen Zweifel mehr, dass ich meine Raffstoren in die Heimautomatisierung integrieren kann.

                          Eine Frage habe ich aber noch zum Key: ich habe mein WMS Netz mittels WMS Stick und WMS Studio erstellt. Dadurch habe ich ja eine Projektdatei (.bin), in der alle Komponenten gespeichert sind.

                          Müsste es nicht so sein, dass der Key und PANID usw. in dieser Datei gespeichert sind? Vielleicht könnte man die aus der Datei extrahieren, so dass die Notwendigkeit entfällt, ein neues Gerät mit der Fernbedienung hinzuzufügen. Ich habe nämlich keine weiteren Geräte mehr..

                          Was meinst du dazu? Und nochmals, vielen Dank!

                          1 Antwort Letzte Antwort
                          0
                          • P Offline
                            P Offline
                            Pman
                            schrieb am zuletzt editiert von
                            #40

                            @Eberhart:

                            Eine Frage habe ich aber noch zum Key: ich habe mein WMS Netz mittels WMS Stick und WMS Studio erstellt. Dadurch habe ich ja eine Projektdatei (.bin), in der alle Komponenten gespeichert sind.

                            Müsste es nicht so sein, dass der Key und PANID usw. in dieser Datei gespeichert sind? Vielleicht könnte man die aus der Datei extrahieren, so dass die Notwendigkeit entfällt, ein neues Gerät mit der Fernbedienung hinzuzufügen. Ich habe nämlich keine weiteren Geräte mehr.. `

                            Das kann gut ein, mit den Projektdateien habe ich mich bisher nicht beschäftigt. Ich denke das mit dem Hinzufügen ist noch nicht ganz klar geworden, du fügst tatsächlich den Stick zum Netzwerk hinzu, kein anderes Gerät. Der Adapter sorgt dafür, dass der Stick so antwortet, als sei er ein Gerät, welches hinzugefügt werden soll und erhält dadurch von der Fernbedienung/Zentrale die nötigen Infos.

                            1 Antwort Letzte Antwort
                            0
                            • E Offline
                              E Offline
                              Eberhart
                              schrieb am zuletzt editiert von
                              #41

                              @Pman:

                              @Eberhart:

                              Eine Frage habe ich aber noch zum Key: ich habe mein WMS Netz mittels WMS Stick und WMS Studio erstellt. Dadurch habe ich ja eine Projektdatei (.bin), in der alle Komponenten gespeichert sind.

                              Müsste es nicht so sein, dass der Key und PANID usw. in dieser Datei gespeichert sind? Vielleicht könnte man die aus der Datei extrahieren, so dass die Notwendigkeit entfällt, ein neues Gerät mit der Fernbedienung hinzuzufügen. Ich habe nämlich keine weiteren Geräte mehr.. `

                              Das kann gut ein, mit den Projektdateien habe ich mich bisher nicht beschäftigt. Ich denke das mit dem Hinzufügen ist noch nicht ganz klar geworden, du fügst tatsächlich den Stick zum Netzwerk hinzu, kein anderes Gerät. Der Adapter sorgt dafür, dass der Stick so antwortet, als sei er ein Gerät, welches hinzugefügt werden soll und erhält dadurch von der Fernbedienung/Zentrale die nötigen Infos. `

                              Und das geht mir jeder Fernbedienung? Ich habe aktuell eine Fernbedienung im Netz, es ist die mit den vielen Tasten, 1002767.

                              Heißt das, wenn ich das Prozedere so durchführe, wie du es beschrieben hast, bleibt mein bestehendes WMS Netz erhalten, nur dass eben iobroker mittels WMS Stick als zusätzlicher Teilnehmer des Netzes agiert?

                              1 Antwort Letzte Antwort
                              0
                              • P Offline
                                P Offline
                                Pman
                                schrieb am zuletzt editiert von
                                #42

                                Genau so ist es, in der Anleitung zur Fernbedienung steht, wie man Geräte hinzufügen und entfernen kann.

                                1 Antwort Letzte Antwort
                                0
                                • E Offline
                                  E Offline
                                  Eberhart
                                  schrieb am zuletzt editiert von
                                  #43

                                  Besten Dank. Ich werde mal alles einrichten und schauen ob es funktioniert.

                                  1 Antwort Letzte Antwort
                                  0
                                  • E Offline
                                    E Offline
                                    Eberhart
                                    schrieb am zuletzt editiert von
                                    #44

                                    Habe es jetzt mal ausprobiert, es klappt alles wie beschrieben. Super. Vielen Dank.

                                    Eune Frage habe ich aber noch: sollten die WMS Komponenten nicht auch Signale von Aktoren im Netz weiterleiten, die keinen unmittelbaren Kontakt zum Sender haben? Mein Raspi stand im Hauswirtschaftsraum und konnte dort nur zwei von dreien WMS Zwischensteckern auffinden. Ich musste den Raspi dann ins Wohnzimmer bringen, wo er alle frei Aktoren gefunden hat. Und das, obwohl der eine Empfänger, der zuerst nicht aufgefunden wurde, sich nur ca. Zwei Meter neben einem der anderen beiden Empfänger befindet. Echt komisch. Wie soll das erst mit der Wetterstation werden, die ich noch nicht angeschlossen habe. Die wird zwei Etagen über dem Erdgeschoss sein…

                                    1 Antwort Letzte Antwort
                                    0
                                    • P Offline
                                      P Offline
                                      Pman
                                      schrieb am zuletzt editiert von
                                      #45

                                      @Eberhart:

                                      Eune Frage habe ich aber noch: sollten die WMS Komponenten nicht auch Signale von Aktoren im Netz weiterleiten, die keinen unmittelbaren Kontakt zum Sender haben? Mein Raspi stand im Hauswirtschaftsraum und konnte dort nur zwei von dreien WMS Zwischensteckern auffinden. Ich musste den Raspi dann ins Wohnzimmer bringen, wo er alle frei Aktoren gefunden hat. Und das, obwohl der eine Empfänger, der zuerst nicht aufgefunden wurde, sich nur ca. Zwei Meter neben einem der anderen beiden Empfänger befindet. Echt komisch. Wie soll das erst mit der Wetterstation werden, die ich noch nicht angeschlossen habe. Die wird zwei Etagen über dem Erdgeschoss sein… `
                                      Ob das Netzwerk ein Mesh aufbaut kann ich nicht sagen, mit dem Stick kommunizieren wir ja auf einer höheren Schicht, was der Stick nicht bekommt, können wir auch nicht auswerten. Die Neigung und Ausrichtung des Sticks kann den Empfang verbessern. Die Empfangsleistung des Sticks ist auch bei mir sehr bescheiden, er wurde im Prinzip ja auch nur zur Konfiguration vor Ort entwickelt und nicht für diesen Zweck hier. Was den Wettersensor angeht: dieser Sendet Broadcasts in rel. kurzen Abständen. Wenn dein Stick nicht jeden davon mitbekommt fällt das kaum auf, so lang hin und wieder etwas empfangen wird.

                                      Du kannst natürlich auch versuchen die Antenne zu verbessern, da müssten die vielen Anleitungen im Internet für Wlan-Sticks (2.4Ghz!) funktionieren.

                                      1 Antwort Letzte Antwort
                                      0
                                      • E Offline
                                        E Offline
                                        Eberhart
                                        schrieb am zuletzt editiert von
                                        #46

                                        @Pman:

                                        Ob das Netzwerk ein Mesh aufbaut kann ich nicht sagen, mit dem Stick kommunizieren wir ja auf einer höheren Schicht, was der Stick nicht bekommt, können wir auch nicht auswerten. Die Neigung und Ausrichtung des Sticks kann den Empfang verbessern. Die Empfangsleistung des Sticks ist auch bei mir sehr bescheiden, er wurde im Prinzip ja auch nur zur Konfiguration vor Ort entwickelt und nicht für diesen Zweck hier. Was den Wettersensor angeht: dieser Sendet Broadcasts in rel. kurzen Abständen. Wenn dein Stick nicht jeden davon mitbekommt fällt das kaum auf, so lang hin und wieder etwas empfangen wird.

                                        Du kannst natürlich auch versuchen die Antenne zu verbessern, da müssten die vielen Anleitungen im Internet für Wlan-Sticks (2.4Ghz!) funktionieren. `

                                        Laut Warema funktioniert das WMS System so, Mesh ist wohl die passende Bezeichnung. Wäre natürlich irgendwie nicht so toll, wenn ich die weiter entfernt gelegenen Raffstoren (die wir noch nachrüsten) nicht erreichen kann. Aber wenn der Stick wie ein normaler Netzteilnehmer eingebunden wird, verstehe ich das mit der höheren Ebene nicht. Wenn beispielsweise bei der Fernbedienung ein Teilnehmer eingelernt wird, und der ist später nicht direkt erreichbar, wenn ihm ein Befehl geschickt wird, müsste dieser Befehl doch auch über das Netz geroutet werden (laut Warema). Dann müsste das doch mit dem Stick in iobroker auch so funktionieren?!

                                        1 Antwort Letzte Antwort
                                        0
                                        • P Offline
                                          P Offline
                                          Pman
                                          schrieb am zuletzt editiert von
                                          #47

                                          > Aber wenn der Stick wie ein normaler Netzteilnehmer eingebunden wird, verstehe ich das mit der höheren Ebene nicht.

                                          Der Stick übernimmt selbstständig die Kommunikation mit dem Netzwerk, er gibt dann über seinen Seriellen Port nur weiter, was er empfangen hat und umgekehrt können wir ihm sagen, was er senden soll. Das passiert beides auf einer abstrakten Ebene ohne Berührung mit technischen Details des Funknetzwerks.

                                          1 Antwort Letzte Antwort
                                          0
                                          Antworten
                                          • In einem neuen Thema antworten
                                          Anmelden zum Antworten
                                          • Älteste zuerst
                                          • Neuste zuerst
                                          • Meiste Stimmen


                                          Support us

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

                                          756

                                          Online

                                          32.4k

                                          Benutzer

                                          81.5k

                                          Themen

                                          1.3m

                                          Beiträge
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                                          ioBroker Community 2014-2025
                                          logo
                                          • Anmelden

                                          • Du hast noch kein Konto? Registrieren

                                          • Anmelden oder registrieren, um zu suchen
                                          • Erster Beitrag
                                            Letzter Beitrag
                                          0
                                          • Home
                                          • Aktuell
                                          • Tags
                                          • Ungelesen 0
                                          • Kategorien
                                          • Unreplied
                                          • Beliebt
                                          • GitHub
                                          • Docu
                                          • Hilfe