Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. TCP-Server für Netzwerk I/O Modul

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    TCP-Server für Netzwerk I/O Modul

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

      Hallo Leute,

      ich habe mir beim Ali dieses Netzwerk I/O Modul besorgt :
      https://de.aliexpress.com/item/32878473705.html

      Dieses 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 abfragen

      Sende 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");
      
      OliverIO 1 Reply Last reply Reply Quote 0
      • OliverIO
        OliverIO @Carsten Eckstein last edited by

        @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

        1 Reply Last reply Reply Quote 0
        • Carsten Eckstein
          Carsten Eckstein last edited by

          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?

          OliverIO 2 Replies Last reply Reply Quote 0
          • OliverIO
            OliverIO @Carsten Eckstein last edited by

            @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

            1 Reply Last reply Reply Quote 0
            • OliverIO
              OliverIO @Carsten Eckstein last edited by OliverIO

              @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 1 Reply Last reply Reply Quote 0
              • AlCalzone
                AlCalzone Developer last edited by

                @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#L208

                Ist 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

                1 Reply Last reply Reply Quote 0
                • Carsten Eckstein
                  Carsten Eckstein @OliverIO last edited by

                  @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");
                  
                  AlCalzone 1 Reply Last reply Reply Quote 0
                  • AlCalzone
                    AlCalzone Developer @Carsten Eckstein last edited by AlCalzone

                    @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();
                    });
                    1 Reply Last reply Reply Quote 0
                    • OliverIO
                      OliverIO last edited by OliverIO

                      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-js

                      Zu 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 aus

                      dann musst du das senden. Das AT kommt mir bekannt vor, so musste man früher Modems ansteuern um ins Internet zu kommen

                      AT+OCCH1=?

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post

                      Support us

                      ioBroker
                      Community Adapters
                      Donate

                      519
                      Online

                      31.8k
                      Users

                      80.0k
                      Topics

                      1.3m
                      Posts

                      3
                      9
                      670
                      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