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.
    • R
      radiorichter last edited by

      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 😄

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

        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 Reply Last reply Reply Quote 0
        • E
          Eberhart last edited by

          @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 Reply Last reply Reply Quote 0
          • P
            Pman last edited by

            @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 Reply Last reply Reply Quote 0
            • E
              Eberhart last edited by

              @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 Reply Last reply Reply Quote 0
              • P
                Pman last edited by

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

                1 Reply Last reply Reply Quote 0
                • E
                  Eberhart last edited by

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

                  1 Reply Last reply Reply Quote 0
                  • E
                    Eberhart last edited by

                    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 Reply Last reply Reply Quote 0
                    • P
                      Pman last edited by

                      @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 Reply Last reply Reply Quote 0
                      • E
                        Eberhart last edited by

                        @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 Reply Last reply Reply Quote 0
                        • P
                          Pman last edited by

                          > 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 Reply Last reply Reply Quote 0
                          • E
                            Eberhart last edited by

                            @Pman:

                            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. `
                            Ich verstehe. Jetzt nehmen wir mal an, dem Stick sind (innerhalb von iobroker) Teilnehmer des Netzes bekannt, die jetzt nicht mehr unmittelbar erreichbar sind, weil sie eben außerhalb der Funkreichweite des Sticks liegen.

                            Müsste es dann nicht so sein, dass der Stick seine Befehle versendet, auch ohne dass der Teilnehmer direkt erreichbar ist, und dieser Befehl wird dann von anderen Teilnehmern des Netzes weitergeleitet? Ich könnte das ja mal ausprobieren bei mir. Wenn das nicht funktioniert, könnte man das noch implementieren?

                            Andererseits - sobald ich das Skript oder den gesamten Raspi mal neu starte, sind doch die gefundenen Teilnehmer des Netzes weg, oder? Das wäre natürlich nicht praktikabel, weil man dann den Stick erst mal wieder in die Nähe der sonst nicht direkt erreichbaren Teilnehmer bringen müsste, um innerhalb des Skripts klar zu machen, aus welchen Teilnehmern das Netz besteht.

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

                              > Müsste es dann nicht so sein, dass der Stick seine Befehle versendet, auch ohne dass der Teilnehmer direkt erreichbar ist, und dieser Befehl wird dann von anderen Teilnehmern des Netzes weitergeleitet?
                              Ist möglich, ich kenne die technischens Details des WMS-Funknetzes nicht, diese sind auch nicht öffentlich.

                              > Wenn das nicht funktioniert, könnte man das noch implementieren?
                              Nein. Wie gesagt, der Stick übernimmt die Kommunikation mit dem Netzwerk komplett, da kann man im Adapter nichts implementieren.

                              > Andererseits - sobald ich das Skript oder den gesamten Raspi mal neu starte, sind doch die gefundenen Teilnehmer des Netzes weg, oder? Das wäre natürlich nicht praktikabel, weil man dann den Stick erst mal wieder in die Nähe der sonst nicht direkt erreichbaren Teilnehmer bringen müsste, um innerhalb des Skripts klar zu machen, aus welchen Teilnehmern das Netz besteht.
                              Der Adapter lässt den Stick periodisch nach neuen Geräten suchen, ob diese Suchanfragen im WMS-Netz weitergeleitet werden order nur Punkt-zu-Punkt gehen weiß ich nicht.

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

                                Dann wär's vermutlich besser die Reichweite des Sticks zu erhöhen. Damit sollte es dann beim Neustart oder ähnlichem kein Problem sein. Oder? 😉

                                Gesendet von meinem KFSUWI mit Tapatalk

                                1 Reply Last reply Reply Quote 0
                                • E
                                  Eberhart last edited by

                                  Verstehe ich es denn richtig, dass die bekannten WMS Geräte bei einem Neustart des Scripts verloren gehen? Wenn ja, könnte man das nicht ändern? Indem ein einmal gefundenes Gerät dauerhaft gespeichert wird? Sofern das intelligente Routing der Befehle erfolgt (ich suche nochmal die WMS Broschüre raus, aus der das hervorgeht), könnte man so auch alle Netzteilnehmer erreichen, die nicht in unmittelbarer Reichweite des Sticks sind.

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

                                    Die Objekte in ioBroker bleiben erhalten nachdem sie einmal erstellt wurden, sind aber erstmal passiv, bis sie im aktuellen Skriptstart auch tatsächlich gefunden wurden.

                                    Sollte sich herausstellen, dass das auffinden von Geräten kein Routing unterstützt, das Empfangen und Senden von Befehlen jedoch schon, könnte man das Skript so abändern, dass einmal gefundene Geräte beim Skriptstart geladen werden. Ohne gesicherte Erkenntnisse dazu lohnt das aber nicht.

                                    1 Reply Last reply Reply Quote 0
                                    • E
                                      Eberhart last edited by

                                      Da ich mittlerweile auf OpenHab umgestiegen bin - gibt's hier jemanden, der dafür ein Binding erstellen könnte? Sollte mit den Erkenntnissen hier doch möglich sein… Mir fehlen leider die Programmierkenntnisse dafür.

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

                                        @ Eberhard: Wie sieht es jetzt eigentlich bei dir mit der Reichweite des wms sticks aus? Hast du da noch was machen können?

                                        Gesendet von meinem HUAWEI VNS-L21 mit Tapatalk

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

                                          @Eberhart:

                                          Da ich mittlerweile auf OpenHab umgestiegen bin - gibt's hier jemanden, der dafür ein Binding erstellen könnte? Sollte mit den Erkenntnissen hier doch möglich sein… Mir fehlen leider die Programmierkenntnisse dafür. `

                                          Im Forum hier geht es um ioBroker :-)) OpenHab ist ein anderes Forum …

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

                                            Hallo zusammen,

                                            das hier ist ein wirklich interessanter Treat und ich habe mich extra deswegen hier angemeldet 😄 😄

                                            Wirklich eine sehr gute Arbeit von euch; etwas vergleichbares zu dem Warema-Protokoll ist sonst nirgendwo zu finden – vielen Dank.

                                            Ein paar Fragen habe ich aber noch. Vielleicht könnt ihr helfen:

                                            1. Was genau ist gemeint mit „Netzwerkschlüssel in umgekehrter Reihenfolge“?

                                            123456ABCD…. wird zu ….CDAB563412 oder

                                            123456ABCD…. wird zu ….DCBA654321

                                            1. Gibt es einen Befehl für den USB-Stick, mit dem die vom Handsender gesendeten Daten mitgelesen werden können (z.B. an die Markise)?

                                            2. Wir bekommt man die SNR von einem Aktor (z.B. Markise) ohne Sensor?

                                            3. Mit welchem Befehl wird eine Markise ausgefahren oder eingefahren?

                                            Edit:

                                            zu 3 -> mit dem Scan-Befehl {R04FFFFFF7020PPPP02} (wurde schon beschrieben)

                                            zu 4 -> mit dem Fahr-Befehl {R06FFFFFF70700pp0FFFFFF00} (pp für Position in %)

                                            LG

                                            rainer

                                            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

                                            667
                                            Online

                                            31.7k
                                            Users

                                            79.7k
                                            Topics

                                            1.3m
                                            Posts

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