NEWS
TCP-Server für Netzwerk I/O Modul
-
Hallo Leute,
ich habe mir beim Ali dieses Netzwerk I/O Modul besorgt :
https://de.aliexpress.com/item/32878473705.htmlDieses Modul hat 4 Inputs und 4 Outputs und fast keine brauchbare Dokumentation.
Bisherige Erkenntnisse:
Es gibt eine Configsoftware ausschließlich in Chinesisch
In der Software stelle ich die Ziel IP und Port ein
Das Modul stellt zu dem angegebenen Server eine Verbindung her
Es lässt sich über "AT"-Befehle steuern und der Status abfragenSende ich an das Modul "AT+OCCH0=?" , kommt als Antwort die Zustände der Inputs:
"+OCCH1:0"
"+OCCH2:0"
"+OCCH3:0"
"+OCCH4:0"Analog dazu lässt sich mit "AT+STACH0=?" der Relais abfragen.
Mit dem Befehl "AT+STACH1=1" lässt sich als Beispiel Relais 1 einschalten.
In Python würde ich das vielleicht noch halbwegs hinbekommen, aber in Javascript sind meine Erfahrungen gleich null.
Ich möchte gerne die Zustände mit einem Intervall von vielleicht 500ms abfragen und in Datenpunkte schreiben und für jedes Relais einen Datenpunkt anlegen welcher dieses dann schaltet.
Meine wahrscheinlich haarsträubenden Gehversuche möchte ich euch natürlich nicht vorenthalten
// Load the TCP Library var net = require('net'); // Keep track of the chat clients var clients = []; // Start a TCP Server var server = net.createServer(function (socket) { // Identify this client socket.name = socket.remoteAddress + ":" + socket.remotePort function checkStatus() { socket.write("AT+OCCH1=?\n"); socket.on('data', function (data) { const state = data.toString().split(':'); if (state[0] = "+OCCH1") { setState('javascript.0.Rolladen.EgSchlafen.Fenster1geschlossen'/*Fenster1geschlossen*/, Boolean(toInt(state[1]))); } }); socket.write("AT+OCCH2=?\n"); socket.on('data', function (data) { const state = data.toString().split(':'); if (state[0] = "+OCCH2") { setState('javascript.0.Rolladen.EgSchlafen.Fenster2geschlossen'/*Fenster2geschlossen*/, Boolean(toInt(state[1]))); } }); socket.write("AT+OCCH3=?\n"); socket.on('data', function (data) { const state = data.toString().split(':'); if (state[0] = "+OCCH3") { setState('javascript.0.Rolladen.EgSchlafen.TasterAuf'/*TasterAuf*/, Boolean(toInt(state[1]))); } }); socket.write("AT+OCCH4=?\n"); socket.on('data', function (data) { const state = data.toString().split(':'); if (state[0] = "+OCCH4") { setState('javascript.0.Rolladen.EgSchlafen.TasterAb'/*TasterAb*/, Boolean(toInt(state[1]))); } }); //console.log(state[1]); }; socket.on('end', function () { server.close(); }); setInterval(checkStatus, 3000); }) server.listen(6000); console.log("Server running at port 6000\n");
-
@Carsten-Eckstein für chinesische übersetzung kann ich dir die google translate app
empfehlen. du machst einen screenshot und lädst den in die app.
dann kannst du markieren was er übersetzen soll -
Die Übersetzung ist nichtmal das größte Problem, sondern dass ich nicht weiß wie ich einen vernünftigen TCP Socket Server in Javascript realisiert bekomme.
Kann mir das jemand helfen und über mein Script mal drüber schauen wo da die groben Patzer liegen?
-
@Carsten-Eckstein wo liegt der code oder ist es schon das was da oben im kasten ist? Ich hab da auch mal was rudimentäres gemacht um per broadcast nach geräten zu suchen
-
@Carsten-Eckstein wenn es der code oben ist, dann fällt mir als erstes auf, dass du zu sehr ein prozedurales verständnis vom code hast.
mit
socket.write("AT+OCCH4=?\n");
sendest du daten
und mit
socket.on('data', function (data) { const state = data.toString().split(':'); if (state[0] = "+OCCH4") { setState('javascript.0.Rolladen.EgSchlafen.TasterAb'/*TasterAb*/, Boolean(toInt(state[1]))); } });
versuchst du genau die antwort zu den daten zu verarbeiten.
da javascript asynchron ist und auch netzverkehr asynchron ist, geht der code wahrscheinlich recht schnell durch ohne das groß was passiert.
wenn du das hier immer neu definierst, dann überschreibst du auch die anderen bearbeitung routinen, die du vorher schon definiert hast.
socket.on('data', function (data) {
schritt 0, warum startest du einen server? wartest du auf anfragen? du bist doch eher client, der die gegenstelle fragt
schritt 1. fasse allen code, in einer on.data zusammen, der die antowrten verarbeitet
schritt2, definiere die bevor du in deinem code irgendetwas sendest.
schritt3, wenn dein senden eine zeitliche abfolge bedingt (also erst das erste und wenn die anwort dazu verarbeitet wurde, dann musst du dich mit promises noch auseinandersetzen.
https://developer.mozilla.org/de/docs/Web/JavaScript/Guide/Using_promises
schritt4: implementiere auch die anderen ONs noch (error,close,timeout,end) damit du zum einen auch fehler in der kommunikation siehst und die Ressourcen auch wieder aufgeräumt werden die du angefordert hast (createserver), sonst birgt das gefahr dir ein sogenanntes speicherleck einzufangen, wenn adapter/skript immer neu aufgerufen wird.ein funktionierendes Beispiel für einen rudimentären Telnet-Client findest du hier:
https://github.com/oweitman/ioBroker.squeezeboxrpc/blob/6adea0dff0e3d31869523e47b27cfd6604ad5246/lib/iosbserver.js#L343 -
@Carsten-Eckstein Mein g-homa Modul hat eine recht ähnliche Weise mit den Steckdosen zu kommunizieren. Vielleicht hilft dir die Server-Klasse (ist allerdings in TypeScript) weiter:
https://github.com/AlCalzone/node-g-homa/blob/d9170283ce9c645be61e3c3dfd6c2d18e0eaf180/src/server.ts#L208Ist etwas umfangreicher, da alle möglichen Eventualitäten bereits abgefangen sind.
Ganz unten ist auch eine Methode, um Befehle an die Module zu senden: https://github.com/AlCalzone/node-g-homa/blob/d9170283ce9c645be61e3c3dfd6c2d18e0eaf180/src/server.ts#L467
-
@OliverIO mein Verständnis von Code liegt vielleicht daran, dass ich es hauptsächlich mit Industriesteuerungen (Siemens u.Ä.) zu tun habe.
0: Ich starte den Server, weil das I/O Modul als Client fungiert und die Verbindung zum Server herstellt.
1: Habe ich gemacht
2: Habe ich auch gemacht
3: Das stelle ich erstmal zurück bis ich den Rest richtig verstanden habe
4: Das mit dem Aufräumen habe ich noch nicht im Griff. Wie kann ich zum Beispiel erreichen dass der TCP Server beendet wird wenn ich das Script anhalte?
Meine neuste Erkenntnis: Sende ich 'AT+OCCH0=?\n' bekomme ich als Antwort 'OCCH1=0\nOCCH2=0\nOCCH3=0\nOCCH4=0\n'
Hier nochmal mein angepasster Code:// Load the TCP Library var net = require('net'); // Start a TCP Server var server = net.createServer(function (socket) { // Identify this client socket.name = socket.remoteAddress + ":" + socket.remotePort console.log(socket.name); socket.on('end', function () { server.close(); }); socket.on('data', function (data) { var newdata = "" + data; var newdatachunks = newdata.split('\n'); for (var i = 0; i < (newdatachunks.length - 1); i++) { const state = newdatachunks[i].toString().split(':'); // console.log(state[0] + " --- " + state[1]); if (state[0] == "+OCCH1") { if (getState('javascript.0.Rolladen.EgSchlafen.Fenster1geschlossen'/*Fenster1geschlossen*/).val != Boolean(toInt(state[1]))) { setState('javascript.0.Rolladen.EgSchlafen.Fenster1geschlossen'/*Fenster1geschlossen*/, Boolean(toInt(state[1]))); } } if (state[0] == "+OCCH2") { if (getState('javascript.0.Rolladen.EgSchlafen.Fenster2geschlossen'/*Fenster2geschlossen*/).val != Boolean(toInt(state[1]))) { setState('javascript.0.Rolladen.EgSchlafen.Fenster2geschlossen'/*Fenster2geschlossen*/, Boolean(toInt(state[1]))); } } if (state[0] == "+OCCH3") { if (getState('javascript.0.Rolladen.EgSchlafen.TasterAuf'/*TasterAuf*/).val != Boolean(toInt(state[1]))) { setState('javascript.0.Rolladen.EgSchlafen.TasterAuf'/*TasterAuf*/, Boolean(toInt(state[1]))); } } if (state[0] == "+OCCH4") { if (getState('javascript.0.Rolladen.EgSchlafen.TasterAb'/*TasterAb*/).val != Boolean(toInt(state[1]))) { setState('javascript.0.Rolladen.EgSchlafen.TasterAb'/*TasterAb*/, Boolean(toInt(state[1]))); } } } }); function checkStatus() { socket.write("AT+OCCH0=?\n"); }; setInterval(checkStatus, 200); }) server.listen(6000); console.log("Server running at port 6000\n");
-
@Carsten-Eckstein sagte in TCP-Server für Netzwerk I/O Modul:
Wie kann ich zum Beispiel erreichen dass der TCP Server beendet wird wenn ich das Script anhalte?
onStop(() => { server.close(); });
-
Zum Thema Server oder client
Wenn du auf Anfragen von aussen wartest ohne das du etwas initiierst, dann ist es ein Server.
Deswegen schreibst du server.listen(6000)
das heißt dein Server wartet auf Anfragen auf Port 6000.Wenn du selbst die Kommunikation immer initiierst, dann bist du ein client und der andere Server (der wartet ja auf Anfragen von dir)
Aufräumen
In IOBroker sagt dir das die Adapterschnittstelle (Funktion unload) ob der adapter beendet wird, den rest musst du tun, da iobroker ja nicht weiß was dein adapter alles machtn
Wenn du ein node skript standalone laufen hast und mit ctrl C stoppst, dann schau hier
https://stackoverflow.com/questions/20165605/detecting-ctrlc-in-node-jsZu deiner neuesten Erkenntnis
zu deinem konkreten Protokoll kann ich dir nicht helfen, da ich das Gerät nicht kenne. Wenn du kein ordentliches datasheet hast, dann darfst du rumprobieren
beachte bei aliexpress wird automatisch übersetzt. sei dir sicher dass nicht auch ein teil der befehle unter umständen übersetzt wurden, was natürlich falsch ist, da der chip das nicht versteht.
wenn du die sprache auf englisch umstellst, dann sehen die befehle besser ausdann musst du das senden. Das AT kommt mir bekannt vor, so musste man früher Modems ansteuern um ins Internet zu kommen
AT+OCCH1=?