madjack84 / ioBroker.ventilation

ioBroker adapter for ventilation systems like Blauberg, RL, Oxxify
MIT License
3 stars 1 forks source link

Vent RL 50RVW does not receive/process commands via UDP #1

Open okuehn opened 2 years ago

okuehn commented 2 years ago

Hi @madjack84, ich habe euren Thread zum Thema SIKU Lüftersteuerung gelesen.

Ich habe drei Lüfter RL 50RVW im EInsatz welche ja baugleich mit dem SIKU RV 50 W Pro WiFi V2 sind. Diese würde ich gerne mit deinem Script bei mir in die Heimsteuerung integrieren. Hierzu habe ich dein node.js script ich entsprechend angepasst (MQTT, IP Adresse Lüfter) und kann auch via mqtt messages z.B. den mode via topic "rl/Bathroom/cmnd/mode" entsprechend publishen (z.B. "ventilation" oder "regeneration"). Allerdings scheint der Lüfter diese Befehle leider nicht zu erhalten. Dein Script meldet aber auch keinen Fehler bei der UDP Kommunikation.
Hast du eine Idee woran es liegen könnte oder wie ich den Fehler/Ablauf bei der UDP Kommunikation mit dem Lüfter am besten loggen und eingrenzen kann?

Hier der console log wenn ich das script starte und via mqtt den mode ändere

<Buffer fd fd 02 10 44 45 46 41 55 4c 54 5f 44 45 56 49 43 45 49 44 04 31 31 31 31 01 01 02 25 b7 5b 06>
connected to mqtt
You will see this message every second
<Buffer fd fd 02 10 44 45 46 41 55 4c 54 5f 44 45 56 49 43 45 49 44 04 31 31 31 31 02 b7 01 35 06>
mode case
<Buffer fd fd 02 10 44 45 46 41 55 4c 54 5f 44 45 56 49 43 45 49 44 04 31 31 31 31 02 b7 01 35 06>
mode case
okuehn commented 2 years ago

ich habe den Fehler gefunden: Offensichtlich muss auch die richtige Device ID angegeben werden. Ich hatte diese zunächst wie in der API Dokumentation beschrieben durch "DEFAULT_DEVICEID" ersetzt.

Nun erhalte ich auch die Status Rückmeldung vom Lüfter (die alle 30sec abgefragt wird) und die Kommandos die ich per mqtt messages publishe werden ebenfalls korrekt vom Lüfter empfangen und umgesetzt.

/opt/ioBroker.ventilation $ node rl.js
<Buffer fd fd 02 10 30 30 33 38 30 30 34 35 35 37 34 32 35 37 31 30 04 31 31 31 31 01 01 02 25 b7 ed 04>
connected to mqtt
You will see this message every second
received:  <Buffer fd fd 02 10 30 30 33 38 30 30 34 35 35 37 34 32 35 37 31 30 04 31 31 31 31 06 01 01 02 01 25 32 b7 01 27 05> { address: '10.0.10.88', family: 'IPv4', port: 4000, size: 36 }

Ich würde dein script gerne via MQTT in openhab integrieren um drei Lüfter zu steuern. Falls ich euch noch irgendwie beim Testen unterstützen kann melde dich einfach kurz bei mir.

Bis dahin erstmal vielen Dank für dein Skript und die Arbeit bisher!

madjack84 commented 2 years ago

Hey, freut mich, dass das jmd weiterhilft. Ich hatte das auch noch erweitert und refactored aber nicht mehr hochgeladen :/ auch multiple instances habe ich nicht gemacht, da ich nur 2 Lüfter im Pairbetrieb habe.

Hier der Code: `var dgram = require("dgram"); var CronJob = require('cron').CronJob; const mqtt = require('mqtt');

var client = dgram.createSocket("udp4"); var PORT = process.env.UDP_PORT||"4000"; var IPadress = process.env.UDP_IP ||"192.168.188.56"; var ID = process.env.RL_ID||"004A002E4353530B"; var IDSZ = "004A00354353530B"; var PWD = "1111" var MQTTserver = process.env.MQTT_IP ||"192.168.188.21"; var MQTTPort = process.env.MQTT_PORT ||"1883";

var mqtt_temp_message = ""; var header = Buffer.from( [ 0xFD, 0xFD, // Beginn des Pakets 0x02, // Protokolltyp 0x10, // ID Blockgroesse ] ); var IDbuf = Buffer.from(ID); var PWDsizebuf = Buffer.from([0x04]); var PWDbuf = Buffer.from(PWD); var writeFlevelbuf = Buffer.from('init'); var writeModebuf = Buffer.from('init');

const clientId = mqtt_${Math.random().toString(16).slice(3)};

var mqtt_url = 'mqtt://${MQTTServer}:${MQTTport}'; //console.log(mqtt_url); const mqtt_client = mqtt.connect(mqtt_url, clientId);

mqtt_client.on('connect', function(){ console.log("connected to mqtt"); mqtt_client.subscribe('rl/Bathroom/cmnd/fan_level'); mqtt_client.subscribe('rl/Bathroom/cmnd/mode'); } );

mqtt_client.on('message', function(topic, message){ //message ist Buffer //console.log(topic); if(topic.includes("fan_level")){ // construct fan_level write message var dataarr = new Uint8Array(1); dataarr[0] = parseInt(message.toString()); var writeFlevelDatabuf = Buffer.from([0x02, 0x02]); writeFlevelbuf = Buffer.concat([header, IDbuf, PWDsizebuf, PWDbuf, writeFlevelDatabuf, Buffer.from(dataarr.buffer)]); var checksum_writeFlevel = calcchecksum(writeFlevelbuf); writeFlevelbuf = Buffer.concat([writeFlevelbuf,checksum2buffer(checksum_writeFlevel)]); console.log(writeFlevelbuf); client.send(writeFlevelbuf, PORT, IPadress); console.log("fan level case"); } else if(topic.includes("mode")){ // construct Mode write message var error = 0; var modedataarr = new Uint8Array(1); if(message.toString() == "ventilation"){modedataarr[0] = 0;} else if(message.toString() == "regeneration"){modedataarr[0] = 1;} else if(message.toString() == "supplyair"){modedataarr[0] = 2;} else { console.log("bad mode command", message.toString()); error = 1; } if(error == 0){ var writeModeDatabuf = Buffer.from([0x02, 0xB7]); writeModebuf = Buffer.concat([header, IDbuf, PWDsizebuf, PWDbuf, writeModeDatabuf, Buffer.from(modedataarr.buffer)]); var checksum_writeMode = calcchecksum(writeModebuf); writeModebuf = Buffer.concat([writeModebuf,checksum2buffer(checksum_writeMode)]); console.log(writeModebuf); client.send(writeModebuf, PORT, IPadress); } console.log("mode case"); } else{ console.log(message.toString()) } });

// UDP client.on("message", function(message, rinfo) { console.log("received: ", message, rinfo); datalen = rinfo.size - 24 - message.readInt8(20); databuf = message.subarray(20+message.readInt8(20)+2, -2) //20 byte upfront, pwd length, pwd, func for (let i=0; i < datalen; i+=2){ //console.log("data = ", databuf[i]); switch(databuf[i]){ case(1): //console.log("RL ist ", databuf[i+1]?"an":"aus"); mqtt_client.publish('/rl/Bathroom/status', databuf[i+1]?"on":"off", { qos: 0, retain: true }); break; case(2): //console.log("Lueftungsstufe ist ", databuf[i+1]); mqtt_client.publish('/rl/Bathroom/fan_level', databuf[i-1]?databuf[i+1].toString():"0", { qos: 0, retain: true }); break; case(37): //0x25 //console.log("Feuchtigkeit Bad ist ", databuf[i+1]); mqtt_client.publish('/rl/Bathroom/humidity', databuf[i+1].toString(), { qos: 0, retain: true }); break; case(183): //0xB7 if(databuf[i+1].toString() == "0"){mqtt_temp_message = "ventilation";} else if(databuf[i+1].toString() == "1"){mqtt_temp_message = "regeneration";} else if(databuf[i+1].toString() == "2"){mqtt_temp_message = "supplyair";} else {mqtt_temp_message = "error"+ databuf[i+1].toString();} mqtt_client.publish('/rl/Bathroom/mode', mqtt_temp_message, { qos: 0, retain: true }); break; default: console.log("unknown ID"); console.log(message, rinfo) } }

});

client.bind(PORT);

function calcchecksum(intbuff){ let checksum = 0; for (let i = 2; i < intbuff.length; i++) { // console.log(newbuff[i]); checksum+=intbuff[i]; } //console.log("checksum = " , checksum); return checksum; }

function checksum2buffer(checksum){ const arr = new Uint8Array(2); arr[0] = checksum%256; arr[1] = checksum/256; return Buffer.from(arr.buffer); }

// setup UDP messages //var Databuf = Buffer.from([0x01, 0xb9, 0x92, 0xa3]); var Databuf = Buffer.from([0x01, 0x01, 0x02, 0x25, 0xB7]);

var list = [header, IDbuf, PWDsizebuf, PWDbuf, Databuf]; var intbuff = Buffer.concat(list);

//calculate checksum let checksum = calcchecksum(intbuff); //const arr = new Uint8Array(2); //arr[0] = checksum%256; //arr[1] = checksum/256; //const checksumbuff = Buffer.from(arr.buffer);

var list2 = [intbuff,checksum2buffer(checksum)]; var getbuff = Buffer.concat(list2); console.log(getbuff);

// <Buffer fd fd 02 10 30 30 34 41 30 30 32 45 34 33 35 33 35 33 30 42 04 31 31 31 31 01 01 02 de 00> var job = new CronJob('/30 ', function() { client.send(getbuff, PORT, IPadress); //console.log('You will see this message every second'); }, null, true, 'Europe/Berlin'); job.start();

//from App //fd fd 02 10 30 30 34 45 30 30 33 35 34 33 35 33 35 33 30 42 04 31 31 31 31 01 b9 92 a3 13 06 //fd fd 02 10 30 30 34 41 30 30 32 45 34 33 35 33 35 33 30 42 04 31 31 31 31 01 b9 92 a3 1e 06 `

okuehn commented 2 years ago

Danke dir! Ich hatte in der Zwischenzeit mit meinem Sohn deinen ursprünglichen Code ein wenig erweitert. Damit kannst du jetzt beliebig viele Fans definieren und steuern.

Wenn du möchtest sende ich dir den Code natürliche gerne zu damit du Ihn bei dir einbauen kannst?

karloslb commented 1 year ago

Hallo zusammen,

@madjack84 ich habe dein Script im Visual Studio Code zum Laufen gebracht. Danke dafür!!!!

Meine Frage an euch: Wie kann ich etwas publishen? Ich bin ein absoluter neuling was JS angeht. Ich versuchte mich einzulesen hat es aber nicht geklappt. Danach habe ich das Script in ioBroker implementiert. Da funktioniert es aber gar nicht. Scheint als würde der Editor manche Funktionen/Atribute nicht kennen? grafik

Ich bin für jegliche Hilfe dankbar! MfG

madjack84 commented 1 year ago

@karloslb : ja ich meine, dass der js version manche links fehlen und ich weiß leider nicht wie man diese darin nachlädt. Allerdings kann ich dir nur empfehlen einen headless Service aus dem Script zu machen. Dieses startet dann beim Boot und läuft schön latent im Hintergrund. Ist auch nicht schwer. Auch mal nach systemd. Da gibt es massig Beispiele im Netz

karloslb commented 1 year ago

Danke für deine Antwort. Eine Frage hätte ich noch: wie kann ich z.B. die Geschwindigkeit ändern? Was muss ich tun, dass Eingaben möglich wären?

madjack84 commented 1 year ago

Ich hoffe ich hab die Frage richtig verstanden...

Das Script selbst ist ein udp to mqtt converter und verbindet sich als Client an einen mqtt Server (IP Adresse 192.168.188.21 in dem Fall) Heißt: nimm einen Linux Rechner, installiere 'apt- get install mosquitto' und starte den Server. Der läuft dann im Hintergrund. Die IP Adresse von dem Rechner im Lüfter Script eintragen und starten. Mit mosquitto_sub 192.168.188.21 # (google} kannst dann lauschen was der Lüfter so erzählt. Mit mosquitto_pub (Google) kannst dem Lüfter dann Kommandos geben. Beispiel (Syntax ausm Kopf) : mosquitto_pub 192.168.188.21 - t 'rl/Bathroom/cmnd/fan_level" - m '2' Also kein js nötig. Das ist ja das schöne an mqtt :) Ansonsten frage nochmal stellen.

karloslb commented 1 year ago

@madjack84: Danke für deine Antwort und deine Hilfe. Ich versuche deine Vorschläge demnächst umzusätzen.

quaker75 commented 10 months ago

Hallo @all, ich bin zufällig bei der Suche nach einer Möglichkeit meinen RL 50RVW Lüfter extern anzusteuern auf diesen Thread gestoßen, und hoffe das noch einer das Beteiligen hier meine Anfrage mitbekommt.

Leider habe ich von Programmierung und Co praktisch gar keine Ahnung, bin aber auf der Suche nach einer Möglichkeit den RL 50RVW in Abhängigkeit eines Wertegebers meiner Rasperrymatic zu steuern.

Im Prinzip würde ich gerne einen Homematic Feuchtesensor als Referenz nehmen. Sobald dieser einen bestimmten Feuchtewert hat, soll der RL 50RVW in den Betriebsmodus Abluft Wechsel Wenn der Wert wieder unterhalb der definierten Grenze fällt, soll der RL 50RVW wieder in den Wärmerückgewinnungs-Modus wechseln.

Ich habe mittlerweile eine Dokumentation von Raumluftshop über die Smartintegration des Lüfters bekommen. Hier steht viel von UDP Paketen, einem Port 4000 und vielen vielen Paket werten :)

So leider ist mir völlig unklar, wie ich dieses definierte Paket an den RL 50RVW in welcher Form auch immer via Rasperrymatic senden kann.

Ich habe an dieser Stelle ein bisschen mit Node Red und Mosquitto getestet, aber wirklich funktioniert hat da gar nichts.

Ich habe die notwendigen Pakete mal via Wireshark mitgetraced, denke auch das das so passen müsste, aber wie bekomme ich jetzt diese endlos lange Anreihung von Zahlen in Form eines Kommandos an den RL?

Wäre toll, wenn mir hier jemanden helfen könnte.

Gruß Sven

karloslb commented 10 months ago

Hallo quaker75,

ich stand vorm selben Problem. Leider bin ich mit den UDP Paketen nicht weiter gekommen. Schlussendlich habe ich das SmartHome System gewechselt. Jetzt funktioniert es so wie ich es mir vorgestellt habe. MfG

quaker75 commented 10 months ago

@karloslb und über welches und wie steuerst du jetz den RL von extern?

karloslb commented 10 months ago

Ich bin auf Homeassistant umgestigen. Die Lüfter sind über WLAN mit einem mini PC verbunden. Ein externer Sensor kann auch über WLAN, Zigbee ect. mit dem Mini PC verbunden werden. Die Bearbeitung der Signale übernimmt die Homeassistant Software und sendet entsprechende Befehle an die Lüfter.

quaker75 commented 10 months ago

Hallo karloslb, irgendwie ist mir das noch nicht ganz klar. Wie / Woher kommen denn jetzt die Befehle an den Lüfter etwas zu ändern? Ich meine das ist ja keine standart Schnittstelle laos irgendwoher muss ja auch der Homeassist seine Infos bekommen? Gruß Sven

karloslb commented 10 months ago

Hallo, das HA ist nur eine Plattform. Man muss s.g. Integration/-en installieren. Diese werden von Nutzern geschrieben und zur Verfügung gestellt. Die Integration sorgt für die Kommunikation zwischen Lüfter und HA. In meinem Fall ist das die EcoVent 2. Was und wann der Lüfter machen soll schreibt man dann im HA selber.