Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. ioBroker Allgemein
    4. IoBroker mit Warema WMS Web Control

    NEWS

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    IoBroker mit Warema WMS Web Control

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

      Ich habe auch mit dem WMS Stick experimentiert. Leider scheint die "Mesh" Funktionalität nicht für die Steuerbefehle (wie die des WMS Studio) zu gelten. Ist der Empfänger ausser Reichweite, so kommt der Fahrbefehl nicht an. Programmiere ich eine Fernbedienung und löse sie am selben Ort aus, wie vorher den WMS Stick, so funktioniert der Fahrbefehl. Kann ein Fahrbefehl einer Fernbedienung überhaupt untersucht werden? Falls ja: Hat schon jemand geprüft, ob sich diese vom "WMS Studio / Studio Pro" unterscheiden?

      1 Reply Last reply Reply Quote 0
      • R
        radiorichter last edited by

        so, war leider unfähig python bei mir am rock64 zum laufen zu bekommen aber habe es am PC installiert und den die Befehle mir angesehen welche an das Webcontrol geschickt werden. Leider hab ich nur das Senden der Befehle geschafft, nicht die Werte wieder abzuholen. aber besser als nichts 😉

        Hab das ganze nun so gemacht, dass ich einfach per Javascript mit dem Exec Block an das Warema schicke und ein kleines Blockly das den Zähler etc erhöht, klappt soweit ganz gut 😉 Vielleicht kanns ja jemand auch für sich nutzen 😉 Den Zähler setze ich einfach nach erreichen eines bestimmten Wertes wieder auf Anfang, das klappt ganz gut 😉

        Hier das was geschickt wird:

        192.168.178.36/protocol.xml?protocol=9099082103020328ffffff&_=1586803111'

        192.168.178.36/ IP adresse
        protocol.xml?protocol= fest
        90 initial
        99 Zähler +4
        0821 Fahrbefehl
        0302 Raum/Rollo wie in App also Raum 03 und Rollo 02 (start bei 0), bei raum größer 9 wird mit zahlen weitergezählt
        03 Festwert
        28 Position mal 2 und in Hex umgewandelt
        ffffff&_ Fahrbefehl
        1586803111 Zähler +4

        und hier der Blockly auszug:
        58970f93-75df-4a30-b624-d7183ee5762b-grafik.png

        1 Reply Last reply Reply Quote 0
        • R
          rendgeor @willjoha last edited by

          @willjoha
          Hallo, du schreibst: "Dieser Schlüssel kann auf zwei Wegen ermittelt werden. Option 1 durch mitlauschen der Seriellen Kommunikation zwischen WMS Studio und WMS Stick. Hierfür benötigt ihr aber euer Projekt mit dem die Anlage parametriert wurde."

          Wie kann man die serielle Kommunikation belauschen?

          1 Reply Last reply Reply Quote 0
          • R
            Rapptor33 last edited by

            Hallo,

            habe mal eine Adapter Anfrage gestellt, wenn noch jemand Interesse daran hat, bitte Daumen Hoch an der Anfrage 👍
            GitHub Link

            6dfc571c-057f-4f27-a0cc-b2eb03b475d7-grafik.png

            T 1 Reply Last reply Reply Quote 0
            • T
              tombox @Rapptor33 last edited by

              @rapptor33 Ich würde mich der Sache annehmen. Geplant ist das ich mir ein Warema Stick besorge und hoffe das die Reichweite passt. Das WMS Webcontrol sieht zwar einfacher aus für ein Adapter aber es lohnt sich für mich nicht den anzuschaffen oder jemand hat einen über.

              R 1 Reply Last reply Reply Quote 0
              • T
                tombox @radiorichter last edited by

                @radiorichter Ich habe mal für die wms webcontrol pro gebaut.
                Gerne mal testen ob es für andere Nutzer auch geht
                https://forum.iobroker.net/topic/45197/test-warema-wms-webcontroller-v0-0-1

                1 Reply Last reply Reply Quote 0
                • R
                  Rapptor33 @tombox last edited by Rapptor33

                  @tombox Hallo, sorry die späte Meldung. Ja werde das gerne testen, super das du dich darum bemühst 👍
                  Ich habe leider noch den alten webcontrol, der wird ja ohne email account betrieben.

                  Wäre es möglich den Adapter auch für die ältere Webcontrol version zu adaptieren?
                  Könnte auch ein Webcontrol zur Verfügung stellen!

                  T 1 Reply Last reply Reply Quote 0
                  • T
                    tombox @Rapptor33 last edited by

                    @rapptor33 Schwierig ich habe mal gesehen wie die app lokal kommnuiziert und das sind alles verschlüsselte hex nachrichten.

                    M 1 Reply Last reply Reply Quote 0
                    • M
                      Murph @tombox last edited by Murph

                      @tombox Hi, da ich auch die ältere Version der/des WMS Webcontrol habe würde ich mich natürlich auch seeeehr über einen adaptierten Adapter freuen! 😊

                      Oder anders gefragt, da die ganz oben beschriebene Methode ja schon eine Weile her ist, funktioniert die Vorgehensweise mit dem Stick noch?
                      Wäre ja eine Alternative da ich den Stick hier sowieso rum liegen habe... 🙄

                      B 1 Reply Last reply Reply Quote 0
                      • B
                        Bender275 @Murph last edited by

                        Hallo zusammen,

                        ich habe eine Warema Markise mit Volant und Wetterstation.
                        Diese wird aktuell mit der schwarzen Fernbedienung WMS Handsender bedient.

                        Wie ist da aktuell der Stand? Man liest einerseits immer wieder von Web Control, aber auch dem WMS Stick; andererseits nur davon, Werte zu senden, aber nicht abzurufen.
                        Der WMS Stick muss anscheinend auch in das System eingelernt werden.

                        Daher die Frage: Ist es möglich,

                        1. den WMS Stick mit der FB anzulernen, oder brauche ich Warema dazu?
                        2. Diesen dann am Raspi mit iobroker zum laufen zu bringen?
                        3. Die Werte der Wetterstation auszulesen? Hier handelt es sich um Regen, Sonnenstärke, Temperatur und Wind - wäre schon echt praktisch, wenn das ginge und
                        4. Darüber dann die Markise UND den Volant zu steuern?

                        Danke!
                        Viele Grüße

                        T 1 Reply Last reply Reply Quote 0
                        • T
                          tombox @Bender275 last edited by

                          @bender275 Meine Empfehlung ist das die WebControl zu verkaufen und gegen eine WebControl Pro zu tauschen aber zum neu programmieren brauchst du dein WMS Stick. Für die Pro gibt es dann ein Adapter

                          B 1 Reply Last reply Reply Quote 0
                          • B
                            Bender275 @tombox last edited by Bender275

                            @tombox Ich habe noch gar keine Web Control - d.h. ich brauche die WebControl Pro und den Stick?
                            Ist das die hier?
                            https://www.ams-elektro.com/Installationsmaterial/Sonstiges-Installationsmaterial/Tor-Rollladenantriebe-Pumpen-Ventilatoren/Zubehoer-fuer-Tor-Rollladenantriebe/Warema-WMS-WebControl-pro-2020920::2135778.html?MODsid=aqarmdqdap0i1banptufro7vjk

                            Wie würde der Adapter heißen? Ich finde gerade nix mit WMS oder Warema.

                            T 1 Reply Last reply Reply Quote 0
                            • T
                              tombox @Bender275 last edited by

                              @bender275 jap genau der gibt es auch für 255€ der ist noch nicht im latest aber bald
                              https://forum.iobroker.net/topic/45197/test-warema-wms-webcontroller-v0-0-1

                              B 1 Reply Last reply Reply Quote 0
                              • B
                                Bender275 @tombox last edited by

                                @tombox
                                Puh, dann brauche ich ja noch den Stick für 50€...
                                Kann man das dann selbst alles (evtl. mit dem WMS Studio) anlernen, oder brauche ich Warema oder den Monteur dazu?

                                Hat jemand nen Screenshot, wie die Werte von der Wetterstation dargestellt werden?

                                T 1 Reply Last reply Reply Quote 0
                                • T
                                  tombox @Bender275 last edited by

                                  @bender275 kann selber angelernt werden gibt Videos. Keine Ahnung ob die Werte von einer Wetter Station übertragen

                                  1 Reply Last reply Reply Quote 0
                                  • 9
                                    9ukj88 @radiorichter last edited by

                                    Hallo, hat jemand den WebSocket (warema-wms-venetian-blinds-ws-api) für Node.js im Einsatz? Ich würde diesen gerne nutzen, ohne iobroker zu installieren. Mein Warema WMS Stick wird korrekt erkannt. Die Daten wie PANID, Serial, wmsKey oder Channel sind vorhanden.

                                    Hat jemand ein konkretes Beispiel für mich, wie ich z.B. mit CURL den Socket (Webservice) ansprechen kann, um Kommandos wie up, down, stop oder status zu senden/empfangen?

                                    Auch würde gerne den Socket als Dienst auf einer Linux Maschine laufen lassen. Die Dokumentation der API ist sehr ausführlich, aber leider reichen meine Kenntnisse nicht aus, um ein praktisches Beispiel mittels CURL aufzusetzen.

                                    Vielen Dank für nützliche Hinweise. 🙂

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

                                      Hi.
                                      Erstmal danke an alle die sich hier die Mühe machen und Laien wie mich unterstützen 🙂
                                      Dann auch großes Dankeschön an alle die am Skript gearbeitet haben um Warema unter iobroker zum Laufen zu bringen. Hat die ganze Zeit tadellos funktioniert! Leider habe ich nun mein System auf die neuste Version gebracht und daher unbemerkt auch serialport V10 installiert.
                                      Da die Version 10 ja "Breaking Changes" hat funktioniert das Skript nun nicht mehr 😞
                                      "Serialport is not a constructor"
                                      Hat jemand ähnliche Probleme gehabt und vllt. schon das Skipt modifiziert? Ich kriege es leider nicht hin...

                                      btw -> Der Adapter für das Webcontrol Pro ist klasse, auch dafür vielen Dank! Leider kann ich damit nicht die Daten von meiner Wetterstation auslesen. Bringt mir also nicht sonderlich viel.

                                      H 1 Reply Last reply Reply Quote 0
                                      • H
                                        Henry9843 @Schmoke last edited by Henry9843

                                        @schmoke ich stand gerade vor dem gleichen Problem. Nach Studie der Änderungsdoku von Serialport und meinen rudimentären Programmierkenntnissen in Javascript, habe ich es bei mir zum Laufen bekommen. Folgende Änderungen sind vorzunehmen:

                                        var SerialPort = require('serialport');
                                        

                                        ersetzen durch:

                                        const {SerialPort} = require('serialport');
                                        const {ReadlineParser} = require('@serialport/parser-readline');
                                        
                                        const port = new SerialPort(PATH, {
                                        
                                        baudRate: 125000,
                                        
                                        parity: 'none',
                                        
                                        dataBits: 8,
                                        
                                        stopBits: 1,
                                        
                                        autoOpen: false,
                                        
                                        });
                                        

                                        ersetzen durch

                                        const port = new SerialPort({path:PATH, 
                                        baudRate: 125000,
                                        autoOpen: false});
                                        
                                        const parser = port.pipe(new SerialPort.parsers.Readline({delimiter: '}'}));
                                        

                                        durch

                                        const parser = port.pipe(new ReadlineParser({delimiter: '}'}));
                                        

                                        Danach sollte es wieder funktionieren. Bei mir ist PATH als

                                        const PATH = '/dev/ttyUSB0'; 
                                        

                                        definiert.

                                        An dieser Stelle vielen Dank an @willjoha und @Pman. Durch die beiden konnte ich erst iobroker in Kombination mit der wms Steuerung einsetzen. Super Job!

                                        Henry

                                        S 1 Reply Last reply Reply Quote 0
                                        • S
                                          Schmoke @Henry9843 last edited by

                                          @henry9843
                                          Es funktioniert!
                                          Vielen Dank!!!!!!!!
                                          Ihr rettet mir mein Wochenende!

                                          1 Reply Last reply Reply Quote 0
                                          • P
                                            Pman last edited by

                                            Habe das Update nun auch hinter mir und hinterlasse hier nochmal meine aktuelle Version des Skripts.

                                            //updated for serialport 10.x
                                            
                                            const { SerialPort } = require('serialport');
                                            const { ReadlineParser } = require('@serialport/parser-readline')
                                            const namespace = '0_userdata.0.Custom.WMS';
                                            log('namespace: ' + namespace);
                                            
                                            //config
                                            const PATH = "/dev/ttyWMS";
                                            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 = 10;  //how often to scan for devices (seconds)
                                            var scanDevicesMax = 3; //stop scanning after discovering all devices
                                            //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 initially
                                                timers.scanInit = setTimeout(function () {
                                                    wmsScan();
                                                }, 5000);
                                                //scan again every scanInterval seconds
                                                timers.scan = setInterval(function () {
                                                    wmsScan();
                                                }, scanInterval * 1000);
                                            }
                                            
                                            //connect to serial port
                                            
                                            const port = new SerialPort({
                                                path: PATH,
                                                baudRate: 125000,
                                                parity: 'none',
                                                dataBits: 8,
                                                stopBits: 1,
                                                autoOpen: false,
                                            });
                                            
                                            //create parser with '}' as delemiter
                                            const parser = port.pipe(new ReadlineParser({ delimiter: '}' }))
                                            
                                            // handle serial port errors
                                            port.on('error', function () {
                                                log('serial port error!', 'warn');
                                                closePort().then((msg) => {
                                                    log(msg, 'info');
                                                }).catch((err) => {
                                                    log(err, 'warn');
                                                });
                                            });
                                            
                                            //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) => {
                                                    return writeAndWaitFor(encodeWMS('switchChannelRequest', {
                                                        panId: PANID
                                                    }), 'a', true);
                                                }).then((line) => {
                                                    init();
                                                }).catch((err) => {
                                                    log(err, 'warn');
                                                    closePort().then((msg) => {
                                                        log(msg, 'info');
                                                    }).catch((err) => {
                                                        log(err, 'warn');
                                                    });
                                                });
                                            }).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', 'info');
                                                    clearInterval(timers.scan);
                                                    if (port && port.isOpen) {
                                                        // close connection
                                                        port.close(() => {
                                                            resolve('port closed')
                                                        });
                                                    } else {
                                                        reject('no port was opened');
                                                    }
                                                });
                                            }
                                            
                                            //on script stop close port
                                            onStop(() => {
                                                clearInterval(timers.scan);
                                                //@todo clear all timers;
                                                closePort().then((msg) => {
                                                    log(msg, 'info');
                                                }).catch((err) => {
                                                    log(err, 'warn');
                                                });
                                            
                                            }, 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('received: ' + JSON.stringify(obj), 'debug');
                                                //process object
                                                setTimeout( () => processWMS(obj), 10);
                                            }
                                            
                                            //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;
                                                    let listener = (line) => {
                                                        log('listener received message: "' + wmsTrim(line) + '" / expected: "' + expect + '"', 'debug');
                                                        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);
                                                });
                                            }
                                            
                                            var portReady = true;
                                            var sendInterval;
                                            function enqueue(data) {
                                                if (typeof data === 'string'){
                                                    writeQueue.push(data);
                                                } 
                                                clearInterval(sendInterval);
                                                sendInterval = setInterval(sendData, 50);
                                            }
                                            function sendData() {
                                                if (writeQueue.length === 0 && portReady) {
                                                    clearInterval(sendInterval);
                                                    return;
                                                }
                                                if (portReady) {
                                                    portReady = false;
                                                    var sendData = writeQueue.shift();
                                                    log('sending ' + sendData, 'debug');
                                                    port.write(sendData);
                                                    port.drain((err) => {
                                                        portReady = true;
                                                    });
                                                }
                                            }
                                            
                                            /* 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, 00: Handsender
                                                            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) {
                                                log('encoding: ' + type + ' with parameters ' + JSON.stringify(parameter), 'debug');
                                                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 || !parameter.deviceType) return false;
                                                        return '{R01' + parameter.dst + '7021' + parameter.panId + parameter.deviceType + (parameter.payload ? parameter.payload : '') + '}'; //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, deviceType: '20', payload: '8FFF03000000000000000000000201010000000000000000'}), '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') {
                                                            let src = '' + obj.payload.src.trim();
                                                            if (knownDevices[src] === true) {
                                                                //log('skipping device: ' + src);
                                                                return;   
                                                            };
                                                            knownDevices[src] = true;
                                                            log('device type 20 found: ' + src);
                                            
                                                            scanDevicesMax--;
                                                            if (scanDevicesMax === 0) {  
                                                                clearInterval(timers.scan);
                                                                log ('stop scanning for devices');
                                                            }
                                            
                                                            
                                                            //log('creating state: ' + namespace + '.Raffstore.' + src + '.position');
                                                            createState(namespace + '.Raffstore.' + src + '.position', 0, {
                                                                type: 'number',
                                                                min: 0,
                                                                max: 100,
                                                                unit: '%'
                                                            });
                                                            //log('creating state: ' + namespace + '.Raffstore.' + src + '.angle');
                                                            createState(namespace + '.Raffstore.' + src + '.angle', 0, {
                                                                type: 'number',
                                                                min: 0,
                                                                max: 90,
                                                                unit: '°'
                                                            }, function () {
                                                                var deviceId = 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(() => {
                                                                        clearInterval(timers[deviceId + 'parameterGetRequestPosition']);
                                                                        var lastValueAngle = -1;
                                                                        var lastValuePosition = -1;
                                                                        var noChange = 0;
                                                                        writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                                                        timers[deviceId + 'parameterGetRequestPosition'] = setInterval(function () {
                                                                            //get parameter periodically until no change is detected
                                                                            log(getState(deviceId + '.position').val + ':' + lastValuePosition + ' | ' + getState(deviceId + '.angle').val + ':' + lastValueAngle, 'info')
                                                                            if (getState(deviceId + '.position').val === lastValuePosition && getState(deviceId + '.angle').val === lastValueAngle) {
                                                                                noChange++;
                                                                                if (noChange === 2) {
                                                                                    clearInterval(timers[deviceId + 'parameterGetRequestPosition']);
                                                                                }
                                                                            } else {
                                                                                noChange = 0;
                                                                            }
                                                                            lastValuePosition = getState(deviceId + '.position').val;
                                                                            lastValueAngle = getState(deviceId + '.angle').val;
                                                                            writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                                                        },  5000 + Math.random() * 1000);
                                                                        //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(() => {
                                                                        clearInterval(timers[deviceId + 'parameterGetRequestPosition']);
                                                                        var lastValueAngle = -1;
                                                                        var lastValuePosition = -1;
                                                                        var noChange = 0;
                                                                        writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                                                        timers[deviceId + 'parameterGetRequestPosition'] = setInterval(function () {
                                                                            //get parameter periodically until no change is detected
                                                                            log(getState(deviceId + '.position').val + ':' + lastValuePosition + ' | ' + getState(deviceId + '.angle').val + ':' + lastValueAngle, 'info');
                                                                            if (getState(deviceId + '.position').val === lastValuePosition && getState(deviceId + '.angle').val === lastValueAngle) {
                                                                                noChange++;
                                                                                if (noChange === 2) {
                                                                                    clearInterval(timers[deviceId + 'parameterGetRequestPosition']);
                                                                                }
                                                                            } else {
                                                                                noChange = 0;
                                                                            }
                                                                            lastValuePosition = getState(deviceId + '.position').val;
                                                                            lastValueAngle = getState(deviceId + '.angle').val;
                                                                            writeAndWaitFor(encodeWMS('parameterGetRequestPosition', {dst: src}), 'a');
                                                                        },  3500 + Math.random() * 1000);
                                                                        //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(namespace + '.Raffstore.' + obj.payload.src + '.position', obj.payload.messagePayload.position, true, 100, true);
                                                                setStateDelayed(namespace + '.Raffstore.' + obj.payload.src + '.angle', obj.payload.messagePayload.angle, true, 100, true);
                                                            default:
                                                                break;
                                                        }
                                                        break;
                                                    case 'weatherBroadcast':
                                                        log('received weatherBroadcast', 'debug');
                                                        let src = '' + obj.payload.src.trim();
                                                        createState(namespace + '.Wetter.' + src + '.temp', 0, {
                                                            type: 'number',
                                                            unit: '°C',
                                                            write: false
                                                        }, function () {
                                                            setStateDelayed(namespace + '.Wetter.' + src + '.temp', obj.payload.messagePayload.temp, true, 100, true);
                                                        });
                                                        createState(namespace + '.Wetter.' + src + '.wind', 0, {
                                                            type: 'number',
                                                            min: 0,
                                                            unit: 'm/s',
                                                            write: false
                                                        }, function () {
                                                            setStateDelayed(namespace + '.Wetter.' + src + '.wind', obj.payload.messagePayload.wind, true, 100, true);
                                                        });
                                                        createState(namespace + '.Wetter.' + src + '.lux', 0, {
                                                            type: 'number',
                                                            min: 0,
                                                            unit: 'lux',
                                                            write: false
                                                        }, function () {
                                                            setStateDelayed(namespace + '.Wetter.' + src + '.lux', obj.payload.messagePayload.lumen, true, 100, true);
                                                        });
                                                        createState(namespace + '.Wetter.' + src + '.rain', false, {
                                                            type: 'boolean',
                                                            write: false
                                                        }, function () {
                                                            setStateDelayed(namespace + '.Wetter.' + src + '.rain', obj.payload.messagePayload.rain, true, 100, true);
                                                        });
                                                        break;
                                                    case 'beckonRequest':
                                                        writeAndWaitFor(encodeWMS('ack', {dst: obj.payload.src}), 'a');
                                                        break;
                                                    case 'controlRequest':
                                                        writeAndWaitFor(encodeWMS('ack', {dst: obj.payload.src}), 'a');
                                                        break;      
                                                    default:
                                                        break;
                                                }
                                            }
                                            
                                            //scan for devices
                                            function wmsScan() {  
                                                log('scanning for devices');
                                                writeAndWaitFor(encodeWMS('scanRequest', {panId: PANID}), 'a');   
                                            }
                                            
                                            
                                            
                                            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

                                            475
                                            Online

                                            31.7k
                                            Users

                                            79.7k
                                            Topics

                                            1.3m
                                            Posts

                                            26
                                            121
                                            27509
                                            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