Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. ioBroker Allgemein
  4. Homelink - Garagentorantrieb Marantec

NEWS

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    22
    1
    1.2k

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    9.2k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    14
    1
    2.5k

Homelink - Garagentorantrieb Marantec

Geplant Angeheftet Gesperrt Verschoben ioBroker Allgemein
69 Beiträge 17 Kommentatoren 10.1k Aufrufe 14 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • D drapo

    Hallo zusammen

    Gibt es gerade mal wieder Probleme mit der Maveo App? Resp. mein Adapter lässt sich nicht mehr starten. Bin ich der einzige oder habt Ihr Leidensgenossen das selbe Problem?

    T Offline
    T Offline
    tombox
    schrieb am zuletzt editiert von
    #48

    @drapo Ich werde mir das zeitnah mal anschauen

    D 2 Antworten Letzte Antwort
    0
    • T tombox

      @drapo Ich werde mir das zeitnah mal anschauen

      D Offline
      D Offline
      drapo
      schrieb am zuletzt editiert von
      #49

      @tombox vielen Dank

      1 Antwort Letzte Antwort
      0
      • T tombox

        @drapo Ich werde mir das zeitnah mal anschauen

        D Offline
        D Offline
        drapo
        schrieb am zuletzt editiert von
        #50

        @tombox wollte mal freundlich nachfragen ob Du dir das bereits ansehen konntest? Fand diese Lösung bis anhin ganz praktisch. Danke auf jeden Fall für Deine Unterstützung.

        T 1 Antwort Letzte Antwort
        0
        • D drapo

          @tombox wollte mal freundlich nachfragen ob Du dir das bereits ansehen konntest? Fand diese Lösung bis anhin ganz praktisch. Danke auf jeden Fall für Deine Unterstützung.

          T Offline
          T Offline
          tombox
          schrieb am zuletzt editiert von
          #51

          @drapo bräuchte nochmal funktionierende Zugangsdaten zum testen ruhig per mail an tombox2020@gmail.com

          D 1 Antwort Letzte Antwort
          0
          • T tombox

            @drapo bräuchte nochmal funktionierende Zugangsdaten zum testen ruhig per mail an tombox2020@gmail.com

            D Offline
            D Offline
            drapo
            schrieb am zuletzt editiert von
            #52

            @tombox mit denen kannst du ja dann meine Garage steuern. Was genau wirst Du mit den Zugangsdaten machen und mit wievielen auf und zu meines Garagentores muss ich rechnen?

            T 1 Antwort Letzte Antwort
            0
            • D drapo

              @tombox mit denen kannst du ja dann meine Garage steuern. Was genau wirst Du mit den Zugangsdaten machen und mit wievielen auf und zu meines Garagentores muss ich rechnen?

              T Offline
              T Offline
              tombox
              schrieb am zuletzt editiert von
              #53

              @drapo Also ich werde Tor nicht öffnen ich muss nur den Login Vorgang und Abruf der geräte Daten checken mehr nicht

              D 1 Antwort Letzte Antwort
              0
              • T tombox

                @drapo Also ich werde Tor nicht öffnen ich muss nur den Login Vorgang und Abruf der geräte Daten checken mehr nicht

                D Offline
                D Offline
                drapo
                schrieb am zuletzt editiert von
                #54

                @tombox ok daten sind raus. Bitte gib mir rasch rückmeldumg wenn du fertig bist dann werde ich das PW wieder ändern

                1 Antwort Letzte Antwort
                0
                • P Offline
                  P Offline
                  Patrick90
                  schrieb am zuletzt editiert von
                  #55

                  Guten Tag,

                  ich habe vom Maveosupport folgende Email erhalten

                  es tut mir sehr leid, dass Sie so lange bereits auf diese Features warten. Leider ist die Integration dieser Systeme sehr aufwändig und mit einer Menge Zertifizierungen verbunden. Ich möchte Ihnen gerne ein Update zu diesem Thema geben:
                  Wir arbeiten aktuell an der Integration des Smart Home Standards MATTER. Hiermit können wir mit einem Standard die Integration in HomeKit, Google Home und Alexa erreichen. Auch Android Auto ist bereits fertig entwickelt, aktuell warten wir hier mit dem Release noch auf die finale Integration von Apple CarPlay.

                  Ist für euch lediglich zur Info.

                  P 1 Antwort Letzte Antwort
                  0
                  • P Patrick90

                    Guten Tag,

                    ich habe vom Maveosupport folgende Email erhalten

                    es tut mir sehr leid, dass Sie so lange bereits auf diese Features warten. Leider ist die Integration dieser Systeme sehr aufwändig und mit einer Menge Zertifizierungen verbunden. Ich möchte Ihnen gerne ein Update zu diesem Thema geben:
                    Wir arbeiten aktuell an der Integration des Smart Home Standards MATTER. Hiermit können wir mit einem Standard die Integration in HomeKit, Google Home und Alexa erreichen. Auch Android Auto ist bereits fertig entwickelt, aktuell warten wir hier mit dem Release noch auf die finale Integration von Apple CarPlay.

                    Ist für euch lediglich zur Info.

                    P Offline
                    P Offline
                    Patrick90
                    schrieb am zuletzt editiert von
                    #56

                    @patrick90

                    kommt mir definitiv länger vor als gerade mal ein Jahr. Ich habe dennoch mal nachgefragt, worauf man jetzt noch wartet.

                    2024-07-30 19_23_29-Window.png

                    R 1 Antwort Letzte Antwort
                    0
                    • P Patrick90

                      @patrick90

                      kommt mir definitiv länger vor als gerade mal ein Jahr. Ich habe dennoch mal nachgefragt, worauf man jetzt noch wartet.

                      2024-07-30 19_23_29-Window.png

                      R Offline
                      R Offline
                      Ritschy2000
                      schrieb am zuletzt editiert von Ritschy2000
                      #57

                      @patrick90 darf man fragen, ob du schon neue Infos erhalten hast ? Die Integration in Android Auto würde mich auch interessieren...

                      1 Antwort Letzte Antwort
                      0
                      • T Offline
                        T Offline
                        TomTom24
                        schrieb am zuletzt editiert von
                        #58

                        Hi,
                        ich habe mir ein Script gebastelt mit JS-Adapter. Das funktioniert sehr gut und man kann darüber einfach Schalter in Homekit anlegen und z.b. die Garage öffnen. Läuft hier seit über einem Jahr einwandfrei. Ab und zu muss der Adapater/Host neu gestartet werden, weil der Host aus irgendwelchen Gründen dann den Client nicht mehr kennt.

                        1. Datenpunkte anlegen
                        2. Dann braucht ihr nur noch ein kleines Script, dass die Werte open, close, stop, lighton, lightoff in den dp_cmd schreibt.
                        3. DeviceName muss so sein, wie Eure Garage in Eurer App heißt!!

                        Wie gesagt, läuft hier sehr zuverlässig.

                        // wenns nicht geht - IP-Adresse Garage prüfen
                        // Benötigt mqtt -wenns nicht geht - IP-Adresse Garage prüfen
                        //
                        //
                        var net = require('net'); 
                        
                        var dp_door = "0_userdata.0.Garage.Garage_Status_Tor"; //door state
                        var dp_light = "0_userdata.0.Garage.Garage_Status_Licht"; //light state
                        var dp_cmd = "0_userdata.0.Garage.Garage_Command2"; //Befehlsdatenpunkt: Mögliche Werte: open, close, stop, lighton, lightoff. Nach Beschreiben wird der Datenpunkt wieder auf leer gesetzt
                        
                        var deviceName = "GARAGENNAME"; 
                        var host = "IP_ADRESSE";
                        var port = 2785;
                        
                        // random client, weil nach Stromausfall das Script nicht mehr lief, erst als anderer Client angegeben wurde.
                        let x = Math.floor((Math.random() * 30) + 1);
                        
                        var client=x.toString; // Client mit übergeben
                        
                        function startClient() {
                            client = new net.Socket();                 // Erzeugen eines neuen Verbindungsobjekts
                            client.connect(port, host, function() {     // Gerät über host:port anwählen und Verbindung erzeugen
                                console.log('cliend started');
                            });
                            client.on('data', function(data) {          // Wenn daten ankommen, dann verarbeiten
                                console.log('client received: ' + data + " for device: " + deviceName);
                                var dataS = data.toString().trim();              // Datenbuffer in lesbaren Text umwandeln
                                switch(dataS) {                           // je nach rückgabewert unterschiedliche Bearbeitung
                                    case "S;"+deviceName+";open":         // wenn open
                                        setState(dp_door,"open",false);             // dann Datenpunkt setzen
                                        setState(dp_door,"open",true);             // dann Datenpunkt setzen
                                        // Garagentür ebenfalls öffnen
                                        setState('alias.0.Garage.Garagentuer'/*Garagentuer auf zu*/, true)
                                        console.log("Script Garage: "+dataS,"info");
                                        break;
                                    case "S;"+deviceName+";closed":
                                        setState(dp_door,"closed",false);
                                        setState(dp_door,"closed",true);
                                        // Garagentür ebenfalls schließen
                                        setState('alias.0.Garage.Garagentuer'/*Garagentuer auf zu*/, false) 
                                        console.log("Script Garage: "+dataS,"info");
                                        break;
                                    case "S;"+deviceName+";opening":
                                        setState(dp_door,"opening",false);
                                        setState(dp_door,"opening",true);
                                        console.log("Script Garage: "+dataS,"info");
                                        break;
                                    case "S;"+deviceName+";closing":
                                        setState(dp_door,"closing",false);
                                        setState(dp_door,"closing",true);
                                        console.log("Script Garage: "+dataS,"info");
                                        break;
                                    case "S;"+deviceName+";lightOn":
                                        setState(dp_light,"lightOn",false);
                                        setState(dp_light,"lightOn",true);
                                        console.log("Script Garage: "+dataS,"info");
                                        break;
                                    case "S;"+deviceName+";lightOff":
                                        setState(dp_light,"lightOff",false);
                                        setState(dp_light,"lightOff",true);
                                        console.log("Script Garage: "+dataS,"info");
                                        break;
                                }
                            });
                            client.on("error",(err)=>{                  // wenn ein Fehler entsteht
                                console.log("client error " + err.toString());
                            });
                            client.on("timeout",()=>{                   // wenn timeout entsteht
                                console.log("client timeout");
                            });
                        }
                        
                        function sendMessage(host, port, message) {
                            return new Promise((resolve, reject) => {     // Funktion ist asynchron, daher Rückgabe promise
                                if (!client) {
                                    console.log("No Client available :"+x);
                                    resolve("Error");
                                    return;
                                }
                                client.write(message);
                                resolve("OK");
                            });
                        }
                        
                        onStop (function(){
                             /* do something when script is stopped */
                             if (client) {
                                console.log('client ended ');
                                client.end();
                             }
                        }, 1000);
                        
                        startClient();
                        
                        on(dp_cmd, function (obj) {                     // trigger wenn datenpunkt beschrieben wird
                         var cmd;
                         if (obj.state.ack || !obj.state.ack) {                       // aber nur wenn es sich um einen unbestätigten wert handelt
                             cmd = String(obj.state.val).toLowerCase();  // Datenpunktinhalt in Kleinbuchstaben umwandeln
                             console.log('execute command: ' + cmd);
                             switch(cmd) {                           // je nach Datenpunktinhalt verschiedene Befehle
                                 case "open":                        // wenn open
                                     sendMessage(host, port, "C;"+deviceName+";open"); // dann richtigen Befehl an Gerät senden
                                     
                                     break;
                                 case "close":
                                     sendMessage(host, port, "C;"+deviceName+";close");
                                     break;
                                 case "stop":
                                     sendMessage(host, port, "C;"+deviceName+";stop");
                                     break;
                                 case "lighton":
                                     sendMessage(host, port, "C;"+deviceName+";lightOn");
                                     break;
                                 case "lightoff":
                                     sendMessage(host, port, "C;"+deviceName+";lightOff");
                                     break;
                             }
                             
                             setState(obj.id, {val: "", ack: false}); // datenpunkt auf leer als bestätigt setzen
                         }
                        });
                        
                        LongbowL D 2 Antworten Letzte Antwort
                        0
                        • T TomTom24

                          Hi,
                          ich habe mir ein Script gebastelt mit JS-Adapter. Das funktioniert sehr gut und man kann darüber einfach Schalter in Homekit anlegen und z.b. die Garage öffnen. Läuft hier seit über einem Jahr einwandfrei. Ab und zu muss der Adapater/Host neu gestartet werden, weil der Host aus irgendwelchen Gründen dann den Client nicht mehr kennt.

                          1. Datenpunkte anlegen
                          2. Dann braucht ihr nur noch ein kleines Script, dass die Werte open, close, stop, lighton, lightoff in den dp_cmd schreibt.
                          3. DeviceName muss so sein, wie Eure Garage in Eurer App heißt!!

                          Wie gesagt, läuft hier sehr zuverlässig.

                          // wenns nicht geht - IP-Adresse Garage prüfen
                          // Benötigt mqtt -wenns nicht geht - IP-Adresse Garage prüfen
                          //
                          //
                          var net = require('net'); 
                          
                          var dp_door = "0_userdata.0.Garage.Garage_Status_Tor"; //door state
                          var dp_light = "0_userdata.0.Garage.Garage_Status_Licht"; //light state
                          var dp_cmd = "0_userdata.0.Garage.Garage_Command2"; //Befehlsdatenpunkt: Mögliche Werte: open, close, stop, lighton, lightoff. Nach Beschreiben wird der Datenpunkt wieder auf leer gesetzt
                          
                          var deviceName = "GARAGENNAME"; 
                          var host = "IP_ADRESSE";
                          var port = 2785;
                          
                          // random client, weil nach Stromausfall das Script nicht mehr lief, erst als anderer Client angegeben wurde.
                          let x = Math.floor((Math.random() * 30) + 1);
                          
                          var client=x.toString; // Client mit übergeben
                          
                          function startClient() {
                              client = new net.Socket();                 // Erzeugen eines neuen Verbindungsobjekts
                              client.connect(port, host, function() {     // Gerät über host:port anwählen und Verbindung erzeugen
                                  console.log('cliend started');
                              });
                              client.on('data', function(data) {          // Wenn daten ankommen, dann verarbeiten
                                  console.log('client received: ' + data + " for device: " + deviceName);
                                  var dataS = data.toString().trim();              // Datenbuffer in lesbaren Text umwandeln
                                  switch(dataS) {                           // je nach rückgabewert unterschiedliche Bearbeitung
                                      case "S;"+deviceName+";open":         // wenn open
                                          setState(dp_door,"open",false);             // dann Datenpunkt setzen
                                          setState(dp_door,"open",true);             // dann Datenpunkt setzen
                                          // Garagentür ebenfalls öffnen
                                          setState('alias.0.Garage.Garagentuer'/*Garagentuer auf zu*/, true)
                                          console.log("Script Garage: "+dataS,"info");
                                          break;
                                      case "S;"+deviceName+";closed":
                                          setState(dp_door,"closed",false);
                                          setState(dp_door,"closed",true);
                                          // Garagentür ebenfalls schließen
                                          setState('alias.0.Garage.Garagentuer'/*Garagentuer auf zu*/, false) 
                                          console.log("Script Garage: "+dataS,"info");
                                          break;
                                      case "S;"+deviceName+";opening":
                                          setState(dp_door,"opening",false);
                                          setState(dp_door,"opening",true);
                                          console.log("Script Garage: "+dataS,"info");
                                          break;
                                      case "S;"+deviceName+";closing":
                                          setState(dp_door,"closing",false);
                                          setState(dp_door,"closing",true);
                                          console.log("Script Garage: "+dataS,"info");
                                          break;
                                      case "S;"+deviceName+";lightOn":
                                          setState(dp_light,"lightOn",false);
                                          setState(dp_light,"lightOn",true);
                                          console.log("Script Garage: "+dataS,"info");
                                          break;
                                      case "S;"+deviceName+";lightOff":
                                          setState(dp_light,"lightOff",false);
                                          setState(dp_light,"lightOff",true);
                                          console.log("Script Garage: "+dataS,"info");
                                          break;
                                  }
                              });
                              client.on("error",(err)=>{                  // wenn ein Fehler entsteht
                                  console.log("client error " + err.toString());
                              });
                              client.on("timeout",()=>{                   // wenn timeout entsteht
                                  console.log("client timeout");
                              });
                          }
                          
                          function sendMessage(host, port, message) {
                              return new Promise((resolve, reject) => {     // Funktion ist asynchron, daher Rückgabe promise
                                  if (!client) {
                                      console.log("No Client available :"+x);
                                      resolve("Error");
                                      return;
                                  }
                                  client.write(message);
                                  resolve("OK");
                              });
                          }
                          
                          onStop (function(){
                               /* do something when script is stopped */
                               if (client) {
                                  console.log('client ended ');
                                  client.end();
                               }
                          }, 1000);
                          
                          startClient();
                          
                          on(dp_cmd, function (obj) {                     // trigger wenn datenpunkt beschrieben wird
                           var cmd;
                           if (obj.state.ack || !obj.state.ack) {                       // aber nur wenn es sich um einen unbestätigten wert handelt
                               cmd = String(obj.state.val).toLowerCase();  // Datenpunktinhalt in Kleinbuchstaben umwandeln
                               console.log('execute command: ' + cmd);
                               switch(cmd) {                           // je nach Datenpunktinhalt verschiedene Befehle
                                   case "open":                        // wenn open
                                       sendMessage(host, port, "C;"+deviceName+";open"); // dann richtigen Befehl an Gerät senden
                                       
                                       break;
                                   case "close":
                                       sendMessage(host, port, "C;"+deviceName+";close");
                                       break;
                                   case "stop":
                                       sendMessage(host, port, "C;"+deviceName+";stop");
                                       break;
                                   case "lighton":
                                       sendMessage(host, port, "C;"+deviceName+";lightOn");
                                       break;
                                   case "lightoff":
                                       sendMessage(host, port, "C;"+deviceName+";lightOff");
                                       break;
                               }
                               
                               setState(obj.id, {val: "", ack: false}); // datenpunkt auf leer als bestätigt setzen
                           }
                          });
                          
                          LongbowL Online
                          LongbowL Online
                          Longbow
                          schrieb am zuletzt editiert von
                          #59

                          @tomtom24

                          Hallo, ich habe das Script gerade probiert.

                          Das ist die Fehlermeldung: script.js.common.Scripte.Auffahrt.Marantec_Steuerung: client error Error: connect ECONNREFUSED 192.168.7.34:2785

                          Also IP stimmt, Name von dem Stick stimmt. An was kann es noch liegen?

                          R 1 Antwort Letzte Antwort
                          0
                          • LongbowL Longbow

                            @tomtom24

                            Hallo, ich habe das Script gerade probiert.

                            Das ist die Fehlermeldung: script.js.common.Scripte.Auffahrt.Marantec_Steuerung: client error Error: connect ECONNREFUSED 192.168.7.34:2785

                            Also IP stimmt, Name von dem Stick stimmt. An was kann es noch liegen?

                            R Offline
                            R Offline
                            Ritschy2000
                            schrieb am zuletzt editiert von Ritschy2000
                            #60

                            @longbow hast du den "neuen" WLAN-Stick oder noch die Variante Stick mit zusätzlichem Gateway?

                            Mit den neuen WLAN-Sticks funktioniert es nicht (soweit mir bekannt ist), da bei diesen die Api nicht aktiviert werden kann.

                            LongbowL 1 Antwort Letzte Antwort
                            0
                            • R Ritschy2000

                              @longbow hast du den "neuen" WLAN-Stick oder noch die Variante Stick mit zusätzlichem Gateway?

                              Mit den neuen WLAN-Sticks funktioniert es nicht (soweit mir bekannt ist), da bei diesen die Api nicht aktiviert werden kann.

                              LongbowL Online
                              LongbowL Online
                              Longbow
                              schrieb am zuletzt editiert von
                              #61

                              @ritschy2000 sagte in Homelink - Garagentorantrieb Marantec:

                              Variante Stic

                              den WLAN Stick, gibt es die andere Variante noch?

                              R 1 Antwort Letzte Antwort
                              0
                              • LongbowL Longbow

                                @ritschy2000 sagte in Homelink - Garagentorantrieb Marantec:

                                Variante Stic

                                den WLAN Stick, gibt es die andere Variante noch?

                                R Offline
                                R Offline
                                Ritschy2000
                                schrieb am zuletzt editiert von
                                #62

                                @longbow direkt bei Maveo nicht. Bei Ebay oder anderen Online- Händlern schon.

                                Suche mal nach "maveo Starter Bundle" oder "Maveo box Starterpaket".
                                Ist dann Gateway + "alter" Stick .... kostet auch "nur" günstige 190 € ;)

                                LongbowL 1 Antwort Letzte Antwort
                                0
                                • R Ritschy2000

                                  @longbow direkt bei Maveo nicht. Bei Ebay oder anderen Online- Händlern schon.

                                  Suche mal nach "maveo Starter Bundle" oder "Maveo box Starterpaket".
                                  Ist dann Gateway + "alter" Stick .... kostet auch "nur" günstige 190 € ;)

                                  LongbowL Online
                                  LongbowL Online
                                  Longbow
                                  schrieb am zuletzt editiert von
                                  #63

                                  @ritschy2000

                                  Danke, habe ich gemacht. Nur leider verbindet sich der Stick nicht mit dem Torantrieb. Habe den X.82, der soll aber gehen, da dieses Bundel mit allen Torantrieben ab 2014 gehen soll... Geht aber nicht leider nicht....

                                  Wer kennst sich mit den Torantrieben Marantec aus und kann mir helfen?

                                  1 Antwort Letzte Antwort
                                  0
                                  • T TomTom24

                                    Hi,
                                    ich habe mir ein Script gebastelt mit JS-Adapter. Das funktioniert sehr gut und man kann darüber einfach Schalter in Homekit anlegen und z.b. die Garage öffnen. Läuft hier seit über einem Jahr einwandfrei. Ab und zu muss der Adapater/Host neu gestartet werden, weil der Host aus irgendwelchen Gründen dann den Client nicht mehr kennt.

                                    1. Datenpunkte anlegen
                                    2. Dann braucht ihr nur noch ein kleines Script, dass die Werte open, close, stop, lighton, lightoff in den dp_cmd schreibt.
                                    3. DeviceName muss so sein, wie Eure Garage in Eurer App heißt!!

                                    Wie gesagt, läuft hier sehr zuverlässig.

                                    // wenns nicht geht - IP-Adresse Garage prüfen
                                    // Benötigt mqtt -wenns nicht geht - IP-Adresse Garage prüfen
                                    //
                                    //
                                    var net = require('net'); 
                                    
                                    var dp_door = "0_userdata.0.Garage.Garage_Status_Tor"; //door state
                                    var dp_light = "0_userdata.0.Garage.Garage_Status_Licht"; //light state
                                    var dp_cmd = "0_userdata.0.Garage.Garage_Command2"; //Befehlsdatenpunkt: Mögliche Werte: open, close, stop, lighton, lightoff. Nach Beschreiben wird der Datenpunkt wieder auf leer gesetzt
                                    
                                    var deviceName = "GARAGENNAME"; 
                                    var host = "IP_ADRESSE";
                                    var port = 2785;
                                    
                                    // random client, weil nach Stromausfall das Script nicht mehr lief, erst als anderer Client angegeben wurde.
                                    let x = Math.floor((Math.random() * 30) + 1);
                                    
                                    var client=x.toString; // Client mit übergeben
                                    
                                    function startClient() {
                                        client = new net.Socket();                 // Erzeugen eines neuen Verbindungsobjekts
                                        client.connect(port, host, function() {     // Gerät über host:port anwählen und Verbindung erzeugen
                                            console.log('cliend started');
                                        });
                                        client.on('data', function(data) {          // Wenn daten ankommen, dann verarbeiten
                                            console.log('client received: ' + data + " for device: " + deviceName);
                                            var dataS = data.toString().trim();              // Datenbuffer in lesbaren Text umwandeln
                                            switch(dataS) {                           // je nach rückgabewert unterschiedliche Bearbeitung
                                                case "S;"+deviceName+";open":         // wenn open
                                                    setState(dp_door,"open",false);             // dann Datenpunkt setzen
                                                    setState(dp_door,"open",true);             // dann Datenpunkt setzen
                                                    // Garagentür ebenfalls öffnen
                                                    setState('alias.0.Garage.Garagentuer'/*Garagentuer auf zu*/, true)
                                                    console.log("Script Garage: "+dataS,"info");
                                                    break;
                                                case "S;"+deviceName+";closed":
                                                    setState(dp_door,"closed",false);
                                                    setState(dp_door,"closed",true);
                                                    // Garagentür ebenfalls schließen
                                                    setState('alias.0.Garage.Garagentuer'/*Garagentuer auf zu*/, false) 
                                                    console.log("Script Garage: "+dataS,"info");
                                                    break;
                                                case "S;"+deviceName+";opening":
                                                    setState(dp_door,"opening",false);
                                                    setState(dp_door,"opening",true);
                                                    console.log("Script Garage: "+dataS,"info");
                                                    break;
                                                case "S;"+deviceName+";closing":
                                                    setState(dp_door,"closing",false);
                                                    setState(dp_door,"closing",true);
                                                    console.log("Script Garage: "+dataS,"info");
                                                    break;
                                                case "S;"+deviceName+";lightOn":
                                                    setState(dp_light,"lightOn",false);
                                                    setState(dp_light,"lightOn",true);
                                                    console.log("Script Garage: "+dataS,"info");
                                                    break;
                                                case "S;"+deviceName+";lightOff":
                                                    setState(dp_light,"lightOff",false);
                                                    setState(dp_light,"lightOff",true);
                                                    console.log("Script Garage: "+dataS,"info");
                                                    break;
                                            }
                                        });
                                        client.on("error",(err)=>{                  // wenn ein Fehler entsteht
                                            console.log("client error " + err.toString());
                                        });
                                        client.on("timeout",()=>{                   // wenn timeout entsteht
                                            console.log("client timeout");
                                        });
                                    }
                                    
                                    function sendMessage(host, port, message) {
                                        return new Promise((resolve, reject) => {     // Funktion ist asynchron, daher Rückgabe promise
                                            if (!client) {
                                                console.log("No Client available :"+x);
                                                resolve("Error");
                                                return;
                                            }
                                            client.write(message);
                                            resolve("OK");
                                        });
                                    }
                                    
                                    onStop (function(){
                                         /* do something when script is stopped */
                                         if (client) {
                                            console.log('client ended ');
                                            client.end();
                                         }
                                    }, 1000);
                                    
                                    startClient();
                                    
                                    on(dp_cmd, function (obj) {                     // trigger wenn datenpunkt beschrieben wird
                                     var cmd;
                                     if (obj.state.ack || !obj.state.ack) {                       // aber nur wenn es sich um einen unbestätigten wert handelt
                                         cmd = String(obj.state.val).toLowerCase();  // Datenpunktinhalt in Kleinbuchstaben umwandeln
                                         console.log('execute command: ' + cmd);
                                         switch(cmd) {                           // je nach Datenpunktinhalt verschiedene Befehle
                                             case "open":                        // wenn open
                                                 sendMessage(host, port, "C;"+deviceName+";open"); // dann richtigen Befehl an Gerät senden
                                                 
                                                 break;
                                             case "close":
                                                 sendMessage(host, port, "C;"+deviceName+";close");
                                                 break;
                                             case "stop":
                                                 sendMessage(host, port, "C;"+deviceName+";stop");
                                                 break;
                                             case "lighton":
                                                 sendMessage(host, port, "C;"+deviceName+";lightOn");
                                                 break;
                                             case "lightoff":
                                                 sendMessage(host, port, "C;"+deviceName+";lightOff");
                                                 break;
                                         }
                                         
                                         setState(obj.id, {val: "", ack: false}); // datenpunkt auf leer als bestätigt setzen
                                     }
                                    });
                                    
                                    D Offline
                                    D Offline
                                    drapo
                                    schrieb am zuletzt editiert von
                                    #64

                                    @tomtom24 ich hatte das auch über längere Zeit einwandfrei und ohne Probleme am Laufen. Seit ein paar Monaten gehts es bei mir nicht mehr. Geht es bei Dir noch?

                                    D 1 Antwort Letzte Antwort
                                    0
                                    • D drapo

                                      @tomtom24 ich hatte das auch über längere Zeit einwandfrei und ohne Probleme am Laufen. Seit ein paar Monaten gehts es bei mir nicht mehr. Geht es bei Dir noch?

                                      D Offline
                                      D Offline
                                      drapo
                                      schrieb am zuletzt editiert von
                                      #65

                                      @drapo hab die box geresettet neu verbunden extra auch ein 2,4ghz wlan netz erstellt und nun funktioniert wieder alles wie eh und je

                                      1 Antwort Letzte Antwort
                                      0
                                      • LongbowL Online
                                        LongbowL Online
                                        Longbow
                                        schrieb am zuletzt editiert von
                                        #66

                                        Hallo in die Runde,

                                        da ich auch so einen Antrieb habe und die Box, hatte ich das Script auch so übernommen.
                                        Leider hing es hin und wieder bei mir, daher habe ich mich dran gesetzt und das nun gebaut.

                                        Hoffe es ist selbst erklärend und gefällt euch, wenn ihr Fragen habt, melde Euch einfach bei mir.

                                        // ===== TCP-Client Garagentor (ioBroker JavaScript) =====
                                        // Robust: Reconnect + Backoff, KeepAlive, sauberes Line-Parsing (S;..., R;...),
                                        // AutoClose nach X Minuten mit Rest-SECONDS-Datenpunkt, DP-Autoanlage,
                                        // Licht-Status als boolean, shutdown-sicher (keine DB-closed-Fehler)
                                        const net = require('net');
                                        
                                        // ==== KONFIG ====
                                        const deviceName = "Auffahrt";
                                        const host = "xxx.xxx.x.xxx";
                                        const port = 2785;
                                        const SEND_NEWLINE = true;
                                        
                                        // ==== BASIS-PFAD ====
                                        const base = "0_userdata.0.Eigene_Datenpunkte.Garage.";
                                        
                                        // ==== DATENPUNKTE ====
                                        const dp_door         = base + "Garage_Status_Tor";          // "open|closed|opening|closing"
                                        const dp_light        = base + "Garage_Status_Licht";        // boolean
                                        const dp_cmd          = base + "Garage_Command";             // "open|close|stop|lighton|lightoff"
                                        const dp_connected    = base + "Garage_TcpConnected";        // boolean
                                        const dp_lastReply    = base + "Garage_LastReply";           // string
                                        const dp_lastError    = base + "Garage_LastError";           // string
                                        const dp_ac_enabled   = base + "AutoClose_Enabled";          // boolean
                                        const dp_ac_delay     = base + "AutoClose_DelayMin";         // number (1..120)
                                        const dp_ac_left_s    = base + "AutoClose_RemainingSec";     // number (Sek., read-only)
                                        const dp_lastOpened   = base + "Garage_LastOpened";          // ISO-Zeit
                                        const dp_lastClosed   = base + "Garage_LastClosed";          // ISO-Zeit
                                        
                                        // ---- Dein vorhandener Notify-DP (nicht anlegen, nur schreiben) ----
                                        const dp_notify = "hm-rega.0.31016"; // bestehender Homematic-ReGa Datenpunkt/Variable
                                        
                                        // ---- Notify-Logik: Frühwarnung & Hysterese ----
                                        const EARLY_TRIGGER_SEC = 60;        // ab so vielen Sekunden vor Auto-Close -> notify = true
                                        const NOTIFY_FALSE_DELAY_MS = 5000;  // Hysterese: erst nach 5s "closed" -> notify = false
                                        let notifyFalseTimer = null;
                                        
                                        // ==== DP-AUTOANLAGE (nur eigene 0_userdata.*) ====
                                        function ensureState(id, defVal, common) {
                                          if (!existsState(id)) {
                                            createState(id, defVal, common, () => log(`State angelegt: ${id}`, 'info'));
                                          }
                                        }
                                        ensureState(dp_door,        '',    { name:'Torstatus',        type:'string',  role:'text',                 read:true, write:false });
                                        ensureState(dp_light,       false, { name:'Lichtstatus',      type:'boolean', role:'indicator.light',      read:true, write:false });
                                        ensureState(dp_cmd,         '',    { name:'Befehl',           type:'string',  role:'text',                 read:true, write:true  });
                                        ensureState(dp_connected,   false, { name:'TCP verbunden',    type:'boolean', role:'indicator.reachable',  read:true, write:false });
                                        ensureState(dp_lastReply,   '',    { name:'Letzte Antwort',   type:'string',  role:'text',                 read:true, write:false });
                                        ensureState(dp_lastError,   '',    { name:'Letzter Fehler',   type:'string',  role:'text',                 read:true, write:false });
                                        ensureState(dp_ac_enabled,  true,  { name:'AutoClose aktiv',  type:'boolean', role:'switch',               read:true, write:true  });
                                        ensureState(dp_ac_delay,    5,     { name:'AutoClose Minuten',type:'number',  role:'level', unit:'min',    read:true, write:true  });
                                        ensureState(dp_ac_left_s,   0,     { name:'Rest-Sekunden',    type:'number',  role:'value', unit:'s',      read:true, write:false });
                                        ensureState(dp_lastOpened,  '',    { name:'Letzte Öffnung',   type:'string',  role:'date',                 read:true, write:false });
                                        ensureState(dp_lastClosed,  '',    { name:'Letzter Verschluss',type:'string', role:'date',                 read:true, write:false });
                                        
                                        // ==== SHUTDOWN-SAFE ====
                                        let shuttingDown = false;
                                        function safeSetState(id, val, ack = true) {
                                          if (shuttingDown) return;
                                          try { setState(id, val, ack); } catch (_) {}
                                        }
                                        
                                        // ==== TCP ====
                                        let client = null;
                                        let reconnectTimer = null;
                                        let reconnectDelayMs = 2000;
                                        const reconnectDelayMaxMs = 30000;
                                        let recvBuffer = '';
                                        
                                        function startClient() {
                                          clearTimeout(reconnectTimer);
                                          client = new net.Socket();
                                          client.setKeepAlive(true, 10000);
                                          client.setEncoding('utf8');
                                        
                                          client.connect(port, host, () => {
                                            log(`[${deviceName}] Verbunden mit ${host}:${port}`, 'info');
                                            safeSetState(dp_connected, true);
                                            reconnectDelayMs = 2000;
                                          });
                                        
                                          client.on('data', (chunk) => {
                                            recvBuffer += chunk;
                                            const parts = recvBuffer.split(/\r?\n|\r/);
                                            recvBuffer = parts.pop();
                                            for (const raw of parts) {
                                              const line = (raw || '').trim();
                                              if (line) handleIncoming(line);
                                            }
                                          });
                                        
                                          client.on('error', (err) => {
                                            log(`[${deviceName}] TCP Fehler: ${err.message}`, 'warn');
                                            safeSetState(dp_connected, false);
                                            safeSetState(dp_lastError, err.message);
                                            scheduleReconnect();
                                          });
                                        
                                          client.on('close', (hadError) => {
                                            log(`[${deviceName}] TCP geschlossen${hadError ? ' (Fehler)' : ''}`, 'warn');
                                            safeSetState(dp_connected, false);
                                            scheduleReconnect();
                                          });
                                        }
                                        
                                        function scheduleReconnect() {
                                          try { if (client) client.destroy(); } catch (_) {}
                                          client = null;
                                          reconnectTimer = setTimeout(startClient, reconnectDelayMs);
                                          reconnectDelayMs = Math.min(Math.round(reconnectDelayMs * 1.5), reconnectDelayMaxMs);
                                        }
                                        
                                        // ==== AUTO-CLOSE ====
                                        let autoCloseTimer = null;
                                        let autoCloseDeadline = 0;
                                        let autoCloseTicker = null;
                                        let acInternalTrigger = false;
                                        
                                        function getAcEnabled() {
                                          const v = getState(dp_ac_enabled)?.val;
                                          return v === true || v === 1 || v === 'true';
                                        }
                                        function getAcDelayMin() {
                                          let m = Number(getState(dp_ac_delay)?.val);
                                          if (!isFinite(m) || m <= 0) m = 5;
                                          return Math.max(1, Math.min(120, Math.floor(m)));
                                        }
                                        
                                        function scheduleAutoClose() {
                                          if (!getAcEnabled()) { safeSetState(dp_ac_left_s, 0); return; }
                                          const min = getAcDelayMin();
                                          autoCloseDeadline = Date.now() + min * 60000;
                                        
                                          clearTimeout(autoCloseTimer);
                                          autoCloseTimer = setTimeout(performAutoClose, min * 60000);
                                        
                                          startAutoCloseTicker();
                                          updateRemainingSeconds();
                                          log(`[${deviceName}] AutoClose geplant in ${min} Min`, 'info');
                                        }
                                        
                                        function performAutoClose() {
                                          if (shuttingDown) return;
                                          autoCloseTimer = null;
                                          const st = getState(dp_door)?.val;
                                          if (st === 'open') {
                                            log(`[${deviceName}] AutoClose ausgelöst -> schließe`, 'info');
                                            acInternalTrigger = true;
                                            try { setState(dp_cmd, { val: 'close', ack: false }); } catch (_) {}
                                          } else {
                                            log(`[${deviceName}] AutoClose übersprungen (Status: ${st})`, 'info');
                                          }
                                          stopAutoCloseTicker();
                                          safeSetState(dp_ac_left_s, 0);
                                          autoCloseDeadline = 0;
                                          // dp_notify bleibt bis "closed" true (Hysterese regelt das Zurücksetzen)
                                        }
                                        
                                        function cancelAutoClose(reason = '', suppressWrite = false) {
                                          if (autoCloseTimer) clearTimeout(autoCloseTimer);
                                          if (autoCloseTicker) clearInterval(autoCloseTicker);
                                          autoCloseTimer = null;
                                          autoCloseTicker = null;
                                          autoCloseDeadline = 0;
                                          if (!suppressWrite) safeSetState(dp_ac_left_s, 0);
                                          if (reason) log(`[${deviceName}] AutoClose abgebrochen: ${reason}`, 'info');
                                        }
                                        
                                        function updateRemainingSeconds() {
                                          if (!autoCloseDeadline || shuttingDown) return;
                                          const secLeft = Math.max(0, Math.ceil((autoCloseDeadline - Date.now()) / 1000));
                                          safeSetState(dp_ac_left_s, secLeft);
                                        
                                          // Frühwarnung: ≤ EARLY_TRIGGER_SEC -> notify true
                                          if (secLeft > 0 && secLeft <= EARLY_TRIGGER_SEC) {
                                            clearTimeout(notifyFalseTimer);
                                            safeSetState(dp_notify, true, /*ack*/ false); // bewusst ack=false, falls Triggers benötigt
                                          }
                                        }
                                        
                                        function startAutoCloseTicker() {
                                          if (autoCloseTicker) return;
                                          autoCloseTicker = setInterval(updateRemainingSeconds, 1000);
                                        }
                                        function stopAutoCloseTicker() {
                                          if (!autoCloseTicker) return;
                                          clearInterval(autoCloseTicker);
                                          autoCloseTicker = null;
                                        }
                                        
                                        // ==== EINGEHEND ====
                                        function handleIncoming(line) {
                                          const parts = line.split(';');
                                          if (parts.length < 2) {
                                            log(`[${deviceName}] Unbekanntes Paket: "${line}"`, 'warn');
                                            return;
                                          }
                                          const prefix = parts[0];
                                        
                                          if (prefix === 'S') {
                                            const dev = parts[1];
                                            const value = parts.slice(2).join(';');
                                            if (dev !== deviceName) return;
                                        
                                            switch (value) {
                                              case 'open':
                                                safeSetState(dp_door, 'open');
                                                safeSetState(dp_lastOpened, new Date().toISOString());
                                                clearTimeout(notifyFalseTimer);
                                                safeSetState(dp_notify, true, /*ack*/ false); // sofort true
                                                scheduleAutoClose();
                                                break;
                                        
                                              case 'opening':
                                                safeSetState(dp_door, 'opening');
                                                clearTimeout(notifyFalseTimer);
                                                safeSetState(dp_notify, true, /*ack*/ false); // sofort true
                                                // kein Cancel hier
                                                break;
                                        
                                              case 'closing':
                                                safeSetState(dp_door, 'closing');
                                                clearTimeout(notifyFalseTimer);
                                                safeSetState(dp_notify, true, /*ack*/ false); // sofort true
                                                cancelAutoClose('Status=closing');
                                                break;
                                        
                                              case 'closed':
                                                safeSetState(dp_door, 'closed');
                                                safeSetState(dp_lastClosed, new Date().toISOString());
                                                cancelAutoClose('Status=closed');
                                                // Hysterese: erst nach 5s false
                                                clearTimeout(notifyFalseTimer);
                                                notifyFalseTimer = setTimeout(() => {
                                                  safeSetState(dp_notify, false, /*ack*/ false);
                                                }, NOTIFY_FALSE_DELAY_MS);
                                                break;
                                        
                                              case 'lightOn':
                                                safeSetState(dp_light, true);
                                                break;
                                        
                                              case 'lightOff':
                                                safeSetState(dp_light, false);
                                                break;
                                        
                                              default:
                                                log(`[${deviceName}] Status: ${value}`, 'info');
                                                break;
                                            }
                                            return;
                                          }
                                        
                                          if (prefix === 'R') {
                                            const code = parts[1] || '';
                                            safeSetState(dp_lastReply, code);
                                            if (/ERR|UNKNOWN/i.test(code)) safeSetState(dp_lastError, code);
                                            else log(`[${deviceName}] Antwort: ${code}`, 'info');
                                            return;
                                          }
                                        
                                          log(`[${deviceName}] Unbekanntes Paket: "${line}"`, 'warn');
                                        }
                                        
                                        // ==== SENDEN ====
                                        function sendMessage(msg) {
                                          return new Promise(resolve => {
                                            if (!client) { log(`[${deviceName}] Kein Client aktiv`, 'warn'); return resolve('Error'); }
                                            try { client.write(SEND_NEWLINE ? (msg + '\n') : msg); resolve('OK'); }
                                            catch (e) { log(`[${deviceName}] Sendefehler: ${e.message}`, 'error'); safeSetState(dp_lastError, e.message); resolve('Error'); }
                                          });
                                        }
                                        
                                        // ==== BEFEHL-TRIGGER ====
                                        on({ id: dp_cmd, change: 'ne' }, async obj => {
                                          if (obj.state.ack) return;
                                          const cmd = String(obj.state.val || '').toLowerCase().trim();
                                        
                                          // Manuelle Befehle canceln AutoClose (interner Trigger nicht)
                                          if (acInternalTrigger) {
                                            log(`[${deviceName}] DP-Command (intern): ${cmd}`, 'info');
                                          } else {
                                            if (cmd === 'open' || cmd === 'close' || cmd === 'stop') {
                                              cancelAutoClose(`Befehl: ${cmd}`);
                                            }
                                          }
                                        
                                          let payload = null;
                                          switch (cmd) {
                                            case 'open':     payload = `C;${deviceName};open`; break;
                                            case 'close':    payload = `C;${deviceName};close`; break;
                                            case 'stop':     payload = `C;${deviceName};stop`; break;
                                            case 'lighton':  payload = `C;${deviceName};lightOn`; break;
                                            case 'lightoff': payload = `C;${deviceName};lightOff`; break;
                                            default:
                                              log(`[${deviceName}] Unbekannter Befehl: ${cmd}`, 'warn');
                                              safeSetState(dp_lastError, `UNKNOWN_CMD:${cmd}`);
                                              break;
                                          }
                                        
                                          if (payload) await sendMessage(payload);
                                          safeSetState(dp_cmd, '', true);
                                        
                                          if (acInternalTrigger) acInternalTrigger = false;
                                        });
                                        
                                        // ==== SETTINGS-ÄNDERUNGEN ====
                                        on({ id: dp_ac_enabled, change: 'ne' }, () => {
                                          const st = getState(dp_door)?.val;
                                          if (getAcEnabled() && st === 'open') scheduleAutoClose();
                                          else cancelAutoClose('AutoClose disabled');
                                        });
                                        on({ id: dp_ac_delay, change: 'ne' }, () => {
                                          const st = getState(dp_door)?.val;
                                          if (getAcEnabled() && st === 'open') scheduleAutoClose();
                                        });
                                        
                                        // ==== START/STOP ====
                                        onStop(() => {
                                          shuttingDown = true;
                                          clearTimeout(reconnectTimer);
                                          clearTimeout(notifyFalseTimer);
                                          if (client) { try { client.destroy(); } catch (_) {} }
                                          cancelAutoClose('Script stop', true);
                                        }, 1000);
                                        
                                        startClient();
                                        
                                        
                                        D 1 Antwort Letzte Antwort
                                        0
                                        • LongbowL Longbow

                                          Hallo in die Runde,

                                          da ich auch so einen Antrieb habe und die Box, hatte ich das Script auch so übernommen.
                                          Leider hing es hin und wieder bei mir, daher habe ich mich dran gesetzt und das nun gebaut.

                                          Hoffe es ist selbst erklärend und gefällt euch, wenn ihr Fragen habt, melde Euch einfach bei mir.

                                          // ===== TCP-Client Garagentor (ioBroker JavaScript) =====
                                          // Robust: Reconnect + Backoff, KeepAlive, sauberes Line-Parsing (S;..., R;...),
                                          // AutoClose nach X Minuten mit Rest-SECONDS-Datenpunkt, DP-Autoanlage,
                                          // Licht-Status als boolean, shutdown-sicher (keine DB-closed-Fehler)
                                          const net = require('net');
                                          
                                          // ==== KONFIG ====
                                          const deviceName = "Auffahrt";
                                          const host = "xxx.xxx.x.xxx";
                                          const port = 2785;
                                          const SEND_NEWLINE = true;
                                          
                                          // ==== BASIS-PFAD ====
                                          const base = "0_userdata.0.Eigene_Datenpunkte.Garage.";
                                          
                                          // ==== DATENPUNKTE ====
                                          const dp_door         = base + "Garage_Status_Tor";          // "open|closed|opening|closing"
                                          const dp_light        = base + "Garage_Status_Licht";        // boolean
                                          const dp_cmd          = base + "Garage_Command";             // "open|close|stop|lighton|lightoff"
                                          const dp_connected    = base + "Garage_TcpConnected";        // boolean
                                          const dp_lastReply    = base + "Garage_LastReply";           // string
                                          const dp_lastError    = base + "Garage_LastError";           // string
                                          const dp_ac_enabled   = base + "AutoClose_Enabled";          // boolean
                                          const dp_ac_delay     = base + "AutoClose_DelayMin";         // number (1..120)
                                          const dp_ac_left_s    = base + "AutoClose_RemainingSec";     // number (Sek., read-only)
                                          const dp_lastOpened   = base + "Garage_LastOpened";          // ISO-Zeit
                                          const dp_lastClosed   = base + "Garage_LastClosed";          // ISO-Zeit
                                          
                                          // ---- Dein vorhandener Notify-DP (nicht anlegen, nur schreiben) ----
                                          const dp_notify = "hm-rega.0.31016"; // bestehender Homematic-ReGa Datenpunkt/Variable
                                          
                                          // ---- Notify-Logik: Frühwarnung & Hysterese ----
                                          const EARLY_TRIGGER_SEC = 60;        // ab so vielen Sekunden vor Auto-Close -> notify = true
                                          const NOTIFY_FALSE_DELAY_MS = 5000;  // Hysterese: erst nach 5s "closed" -> notify = false
                                          let notifyFalseTimer = null;
                                          
                                          // ==== DP-AUTOANLAGE (nur eigene 0_userdata.*) ====
                                          function ensureState(id, defVal, common) {
                                            if (!existsState(id)) {
                                              createState(id, defVal, common, () => log(`State angelegt: ${id}`, 'info'));
                                            }
                                          }
                                          ensureState(dp_door,        '',    { name:'Torstatus',        type:'string',  role:'text',                 read:true, write:false });
                                          ensureState(dp_light,       false, { name:'Lichtstatus',      type:'boolean', role:'indicator.light',      read:true, write:false });
                                          ensureState(dp_cmd,         '',    { name:'Befehl',           type:'string',  role:'text',                 read:true, write:true  });
                                          ensureState(dp_connected,   false, { name:'TCP verbunden',    type:'boolean', role:'indicator.reachable',  read:true, write:false });
                                          ensureState(dp_lastReply,   '',    { name:'Letzte Antwort',   type:'string',  role:'text',                 read:true, write:false });
                                          ensureState(dp_lastError,   '',    { name:'Letzter Fehler',   type:'string',  role:'text',                 read:true, write:false });
                                          ensureState(dp_ac_enabled,  true,  { name:'AutoClose aktiv',  type:'boolean', role:'switch',               read:true, write:true  });
                                          ensureState(dp_ac_delay,    5,     { name:'AutoClose Minuten',type:'number',  role:'level', unit:'min',    read:true, write:true  });
                                          ensureState(dp_ac_left_s,   0,     { name:'Rest-Sekunden',    type:'number',  role:'value', unit:'s',      read:true, write:false });
                                          ensureState(dp_lastOpened,  '',    { name:'Letzte Öffnung',   type:'string',  role:'date',                 read:true, write:false });
                                          ensureState(dp_lastClosed,  '',    { name:'Letzter Verschluss',type:'string', role:'date',                 read:true, write:false });
                                          
                                          // ==== SHUTDOWN-SAFE ====
                                          let shuttingDown = false;
                                          function safeSetState(id, val, ack = true) {
                                            if (shuttingDown) return;
                                            try { setState(id, val, ack); } catch (_) {}
                                          }
                                          
                                          // ==== TCP ====
                                          let client = null;
                                          let reconnectTimer = null;
                                          let reconnectDelayMs = 2000;
                                          const reconnectDelayMaxMs = 30000;
                                          let recvBuffer = '';
                                          
                                          function startClient() {
                                            clearTimeout(reconnectTimer);
                                            client = new net.Socket();
                                            client.setKeepAlive(true, 10000);
                                            client.setEncoding('utf8');
                                          
                                            client.connect(port, host, () => {
                                              log(`[${deviceName}] Verbunden mit ${host}:${port}`, 'info');
                                              safeSetState(dp_connected, true);
                                              reconnectDelayMs = 2000;
                                            });
                                          
                                            client.on('data', (chunk) => {
                                              recvBuffer += chunk;
                                              const parts = recvBuffer.split(/\r?\n|\r/);
                                              recvBuffer = parts.pop();
                                              for (const raw of parts) {
                                                const line = (raw || '').trim();
                                                if (line) handleIncoming(line);
                                              }
                                            });
                                          
                                            client.on('error', (err) => {
                                              log(`[${deviceName}] TCP Fehler: ${err.message}`, 'warn');
                                              safeSetState(dp_connected, false);
                                              safeSetState(dp_lastError, err.message);
                                              scheduleReconnect();
                                            });
                                          
                                            client.on('close', (hadError) => {
                                              log(`[${deviceName}] TCP geschlossen${hadError ? ' (Fehler)' : ''}`, 'warn');
                                              safeSetState(dp_connected, false);
                                              scheduleReconnect();
                                            });
                                          }
                                          
                                          function scheduleReconnect() {
                                            try { if (client) client.destroy(); } catch (_) {}
                                            client = null;
                                            reconnectTimer = setTimeout(startClient, reconnectDelayMs);
                                            reconnectDelayMs = Math.min(Math.round(reconnectDelayMs * 1.5), reconnectDelayMaxMs);
                                          }
                                          
                                          // ==== AUTO-CLOSE ====
                                          let autoCloseTimer = null;
                                          let autoCloseDeadline = 0;
                                          let autoCloseTicker = null;
                                          let acInternalTrigger = false;
                                          
                                          function getAcEnabled() {
                                            const v = getState(dp_ac_enabled)?.val;
                                            return v === true || v === 1 || v === 'true';
                                          }
                                          function getAcDelayMin() {
                                            let m = Number(getState(dp_ac_delay)?.val);
                                            if (!isFinite(m) || m <= 0) m = 5;
                                            return Math.max(1, Math.min(120, Math.floor(m)));
                                          }
                                          
                                          function scheduleAutoClose() {
                                            if (!getAcEnabled()) { safeSetState(dp_ac_left_s, 0); return; }
                                            const min = getAcDelayMin();
                                            autoCloseDeadline = Date.now() + min * 60000;
                                          
                                            clearTimeout(autoCloseTimer);
                                            autoCloseTimer = setTimeout(performAutoClose, min * 60000);
                                          
                                            startAutoCloseTicker();
                                            updateRemainingSeconds();
                                            log(`[${deviceName}] AutoClose geplant in ${min} Min`, 'info');
                                          }
                                          
                                          function performAutoClose() {
                                            if (shuttingDown) return;
                                            autoCloseTimer = null;
                                            const st = getState(dp_door)?.val;
                                            if (st === 'open') {
                                              log(`[${deviceName}] AutoClose ausgelöst -> schließe`, 'info');
                                              acInternalTrigger = true;
                                              try { setState(dp_cmd, { val: 'close', ack: false }); } catch (_) {}
                                            } else {
                                              log(`[${deviceName}] AutoClose übersprungen (Status: ${st})`, 'info');
                                            }
                                            stopAutoCloseTicker();
                                            safeSetState(dp_ac_left_s, 0);
                                            autoCloseDeadline = 0;
                                            // dp_notify bleibt bis "closed" true (Hysterese regelt das Zurücksetzen)
                                          }
                                          
                                          function cancelAutoClose(reason = '', suppressWrite = false) {
                                            if (autoCloseTimer) clearTimeout(autoCloseTimer);
                                            if (autoCloseTicker) clearInterval(autoCloseTicker);
                                            autoCloseTimer = null;
                                            autoCloseTicker = null;
                                            autoCloseDeadline = 0;
                                            if (!suppressWrite) safeSetState(dp_ac_left_s, 0);
                                            if (reason) log(`[${deviceName}] AutoClose abgebrochen: ${reason}`, 'info');
                                          }
                                          
                                          function updateRemainingSeconds() {
                                            if (!autoCloseDeadline || shuttingDown) return;
                                            const secLeft = Math.max(0, Math.ceil((autoCloseDeadline - Date.now()) / 1000));
                                            safeSetState(dp_ac_left_s, secLeft);
                                          
                                            // Frühwarnung: ≤ EARLY_TRIGGER_SEC -> notify true
                                            if (secLeft > 0 && secLeft <= EARLY_TRIGGER_SEC) {
                                              clearTimeout(notifyFalseTimer);
                                              safeSetState(dp_notify, true, /*ack*/ false); // bewusst ack=false, falls Triggers benötigt
                                            }
                                          }
                                          
                                          function startAutoCloseTicker() {
                                            if (autoCloseTicker) return;
                                            autoCloseTicker = setInterval(updateRemainingSeconds, 1000);
                                          }
                                          function stopAutoCloseTicker() {
                                            if (!autoCloseTicker) return;
                                            clearInterval(autoCloseTicker);
                                            autoCloseTicker = null;
                                          }
                                          
                                          // ==== EINGEHEND ====
                                          function handleIncoming(line) {
                                            const parts = line.split(';');
                                            if (parts.length < 2) {
                                              log(`[${deviceName}] Unbekanntes Paket: "${line}"`, 'warn');
                                              return;
                                            }
                                            const prefix = parts[0];
                                          
                                            if (prefix === 'S') {
                                              const dev = parts[1];
                                              const value = parts.slice(2).join(';');
                                              if (dev !== deviceName) return;
                                          
                                              switch (value) {
                                                case 'open':
                                                  safeSetState(dp_door, 'open');
                                                  safeSetState(dp_lastOpened, new Date().toISOString());
                                                  clearTimeout(notifyFalseTimer);
                                                  safeSetState(dp_notify, true, /*ack*/ false); // sofort true
                                                  scheduleAutoClose();
                                                  break;
                                          
                                                case 'opening':
                                                  safeSetState(dp_door, 'opening');
                                                  clearTimeout(notifyFalseTimer);
                                                  safeSetState(dp_notify, true, /*ack*/ false); // sofort true
                                                  // kein Cancel hier
                                                  break;
                                          
                                                case 'closing':
                                                  safeSetState(dp_door, 'closing');
                                                  clearTimeout(notifyFalseTimer);
                                                  safeSetState(dp_notify, true, /*ack*/ false); // sofort true
                                                  cancelAutoClose('Status=closing');
                                                  break;
                                          
                                                case 'closed':
                                                  safeSetState(dp_door, 'closed');
                                                  safeSetState(dp_lastClosed, new Date().toISOString());
                                                  cancelAutoClose('Status=closed');
                                                  // Hysterese: erst nach 5s false
                                                  clearTimeout(notifyFalseTimer);
                                                  notifyFalseTimer = setTimeout(() => {
                                                    safeSetState(dp_notify, false, /*ack*/ false);
                                                  }, NOTIFY_FALSE_DELAY_MS);
                                                  break;
                                          
                                                case 'lightOn':
                                                  safeSetState(dp_light, true);
                                                  break;
                                          
                                                case 'lightOff':
                                                  safeSetState(dp_light, false);
                                                  break;
                                          
                                                default:
                                                  log(`[${deviceName}] Status: ${value}`, 'info');
                                                  break;
                                              }
                                              return;
                                            }
                                          
                                            if (prefix === 'R') {
                                              const code = parts[1] || '';
                                              safeSetState(dp_lastReply, code);
                                              if (/ERR|UNKNOWN/i.test(code)) safeSetState(dp_lastError, code);
                                              else log(`[${deviceName}] Antwort: ${code}`, 'info');
                                              return;
                                            }
                                          
                                            log(`[${deviceName}] Unbekanntes Paket: "${line}"`, 'warn');
                                          }
                                          
                                          // ==== SENDEN ====
                                          function sendMessage(msg) {
                                            return new Promise(resolve => {
                                              if (!client) { log(`[${deviceName}] Kein Client aktiv`, 'warn'); return resolve('Error'); }
                                              try { client.write(SEND_NEWLINE ? (msg + '\n') : msg); resolve('OK'); }
                                              catch (e) { log(`[${deviceName}] Sendefehler: ${e.message}`, 'error'); safeSetState(dp_lastError, e.message); resolve('Error'); }
                                            });
                                          }
                                          
                                          // ==== BEFEHL-TRIGGER ====
                                          on({ id: dp_cmd, change: 'ne' }, async obj => {
                                            if (obj.state.ack) return;
                                            const cmd = String(obj.state.val || '').toLowerCase().trim();
                                          
                                            // Manuelle Befehle canceln AutoClose (interner Trigger nicht)
                                            if (acInternalTrigger) {
                                              log(`[${deviceName}] DP-Command (intern): ${cmd}`, 'info');
                                            } else {
                                              if (cmd === 'open' || cmd === 'close' || cmd === 'stop') {
                                                cancelAutoClose(`Befehl: ${cmd}`);
                                              }
                                            }
                                          
                                            let payload = null;
                                            switch (cmd) {
                                              case 'open':     payload = `C;${deviceName};open`; break;
                                              case 'close':    payload = `C;${deviceName};close`; break;
                                              case 'stop':     payload = `C;${deviceName};stop`; break;
                                              case 'lighton':  payload = `C;${deviceName};lightOn`; break;
                                              case 'lightoff': payload = `C;${deviceName};lightOff`; break;
                                              default:
                                                log(`[${deviceName}] Unbekannter Befehl: ${cmd}`, 'warn');
                                                safeSetState(dp_lastError, `UNKNOWN_CMD:${cmd}`);
                                                break;
                                            }
                                          
                                            if (payload) await sendMessage(payload);
                                            safeSetState(dp_cmd, '', true);
                                          
                                            if (acInternalTrigger) acInternalTrigger = false;
                                          });
                                          
                                          // ==== SETTINGS-ÄNDERUNGEN ====
                                          on({ id: dp_ac_enabled, change: 'ne' }, () => {
                                            const st = getState(dp_door)?.val;
                                            if (getAcEnabled() && st === 'open') scheduleAutoClose();
                                            else cancelAutoClose('AutoClose disabled');
                                          });
                                          on({ id: dp_ac_delay, change: 'ne' }, () => {
                                            const st = getState(dp_door)?.val;
                                            if (getAcEnabled() && st === 'open') scheduleAutoClose();
                                          });
                                          
                                          // ==== START/STOP ====
                                          onStop(() => {
                                            shuttingDown = true;
                                            clearTimeout(reconnectTimer);
                                            clearTimeout(notifyFalseTimer);
                                            if (client) { try { client.destroy(); } catch (_) {} }
                                            cancelAutoClose('Script stop', true);
                                          }, 1000);
                                          
                                          startClient();
                                          
                                          
                                          D Offline
                                          D Offline
                                          drapo
                                          schrieb am zuletzt editiert von drapo
                                          #67

                                          @longbow vielen Dank fürs Teilen. Funktioniert Dein Script ohne hänger (von Zeit zu Zeit habe ich diese auch)? Resp. wie lange hast Du es bereits in Verwendung?

                                          LongbowL 1 Antwort Letzte Antwort
                                          0
                                          Antworten
                                          • In einem neuen Thema antworten
                                          Anmelden zum Antworten
                                          • Älteste zuerst
                                          • Neuste zuerst
                                          • Meiste Stimmen


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate
                                          FAQ Cloud / IOT
                                          HowTo: Node.js-Update
                                          HowTo: Backup/Restore
                                          Downloads
                                          BLOG

                                          680

                                          Online

                                          32.5k

                                          Benutzer

                                          81.7k

                                          Themen

                                          1.3m

                                          Beiträge
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                                          ioBroker Community 2014-2025
                                          logo
                                          • Anmelden

                                          • Du hast noch kein Konto? Registrieren

                                          • Anmelden oder registrieren, um zu suchen
                                          • Erster Beitrag
                                            Letzter Beitrag
                                          0
                                          • Home
                                          • Aktuell
                                          • Tags
                                          • Ungelesen 0
                                          • Kategorien
                                          • Unreplied
                                          • Beliebt
                                          • GitHub
                                          • Docu
                                          • Hilfe