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. Skripten / Logik
  4. Node-Red
  5. NodeRed - SendTo Proxy mit JS

NEWS

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    22
    1
    1.1k

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

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

NodeRed - SendTo Proxy mit JS

Geplant Angeheftet Gesperrt Verschoben Node-Red
8 Beiträge 2 Kommentatoren 882 Aufrufe 2 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.
  • mickymM Offline
    mickymM Offline
    mickym
    Most Active
    schrieb am zuletzt editiert von
    #1

    Neuer Thread - um die fehlende Funktion der sendTo Funktionalität an diverse Adapter auszugleichen, habe ich ein kleines Javascript verfasst.

    https://github.com/ioBroker/ioBroker.node-red/issues/291

    Dazu legt man einen Datenpunkt unter 0_userdata.0 an und bekommt das Ergebnis entweder in dem gleichen Datenpunkt oder in unterschiedlichen Datenpunkten.

    So kann man für verschiedene Abfragen immer den gleichen Eingangs (Query) Datenpunkt nehmen, aber auch unterschiedliche Ausgangspunkte.

    Jeder Flow bzw. jedes Script, das ich hier poste implementiert jeder auf eigene Gefahr. Flows und Scripts können Fehler aufweisen und weder der Seitenbetreiber noch ich persönlich können hierfür haftbar gemacht werden. Das gleiche gilt für Empfehlungen aller Art.

    1 Antwort Letzte Antwort
    1
    • mickymM Offline
      mickymM Offline
      mickym
      Most Active
      schrieb am zuletzt editiert von mickym
      #2

      So nun im Detail - hier das Javascript, dass man importieren muss und das stellvertretend für NodeRed - die Nachricht an den entsprechenden Adapter schickt:

      EDIT - so noch ein paar kleine Nacharbeiten notwendig - da man ja nur Strings durch die Gegend schicken darf und keine Objekte:

      Manche Adapter liefern ja auch gar nichts zurück.

      So hier nun das Javascript - was natürlich immer aktiv bleiben muss. ;)

      /**
      * Zweck:      Setzt für einen NodeRed Flow - SendTo Kommandos an verschiedene Adapter ab
      * Datum:      17.08.2022
      * Autor:      @mickym
      */
       
      // In die Variable exchangeWithNodeRed den Pfad des Datenpunktes auswählen, der als Trigger verwendet wird
      /********************************************************************************************************* 
       *  In den Datenpunkt muss ein Objekt von Node Red mit folgenden Eigenschaften übergeben werden:
       *  {
          "adapter": <Adapterinstanz oder Adapter z.Bsp mqtt.0, sql.0>,
          "command": <Kommando - hängt vom jeweilige Adapter ab - bei sql zum Beispiel query, bei manchen Adaptern auch nicht erforderlich>,
          "message": <Nachricht, die an den Adapter geschickt wird>,
          "result": <optional: Pfad zum Datenpunkt, wo das Ergebnis als String abgespeichert wird, ansonsten wird der Trigger als Ausgabepunkt verwendet>
          }
       * 
       * 
      */
      var exchangeWithNodeRed = "0_userdata.0.NodeRed.sendTo";
      
      on({id: exchangeWithNodeRed, change: 'any', ack: false},function (obj) {
      
          // console.log(obj.state.val);
          var val = JSON.parse(obj.state.val);
         
          var returnResult;
      
          // console.log("adapter: " + val.adapter);
          // console.log("command: " + val.command);
          // console.log("message: " + val.message);
          // console.log("result: " + val.result); 
      
          if (val.result === undefined) returnResult = exchangeWithNodeRed; else returnResult =val.result;
       
          if (val.command === undefined){
              // console.log("no command");
              sendTo(val.adapter,val.message,function (result) {
                  if (result.error) setState(returnResult,result.error,true); else setState(returnResult,JSON.stringify(result.result),true);
                  })
          } else {
              // console.log("command: " + val.command);
              sendTo(val.adapter, val.command, val.message, function (result) {
                  if (result.error) setState(returnResult,result.error,true); else setState(returnResult,JSON.stringify(result.result),true);
              });
      
          }
        
      });
      

      Wie gesagt ich habe immer den gleichen Datenpunkt für die sendTo Funktion verwendet und ggf. unterschiedliche Rückgabe Punkte muss aber nicht sein.

      Schauen wir uns mal an, wie man so über den MQTT-Adapter Nachrichten published:

      d954535f-f627-4f71-8126-c89a2d4dc9a3-image.png

      Herzstück für alle Abfragen zu einem Adapter ist die Change-Node, daraus wird dann das Objekt gemacht, dass als JSON zu dem Austauschdatenpunkt geschickt wird.:
      3ca0ad5c-4dec-49cf-a63b-a339c8a7c194-image.png

      Hier nun eine Beispiel mit Rückgabe anhand des SQL-Adapters:

      Hier die SQL Abfrage:
      2a6c3ee2-67f2-4e78-beff-abbb446f2b9a-image.png

      und hier die Change-Node:
      ec5cfc60-2365-480b-879a-5cd2e60b4da1-image.png

      einmal direkt das Ergebnis geholt oder einen neuen Flow triggern lassen:

      10bb24fb-1849-4c07-8251-97196c332a38-image.png

      Hier mal alles zum Import:

      [
         {
             "id": "7ae04fc8f05dccd4",
             "type": "inject",
             "z": "30f50cdc81f34302",
             "name": "SQL Query",
             "props": [
                 {
                     "p": "payload"
                 }
             ],
             "repeat": "",
             "crontab": "",
             "once": false,
             "onceDelay": 0.1,
             "topic": "",
             "payload": "SELECT  id,name FROM iobroker.sources",
             "payloadType": "str",
             "x": 120,
             "y": 140,
             "wires": [
                 [
                     "905eccb6718c33b1"
                 ]
             ]
         },
         {
             "id": "fd62cf142cca7aec",
             "type": "ioBroker out",
             "z": "30f50cdc81f34302",
             "name": "sendTo",
             "topic": "0_userdata.0.NodeRed.sendTo",
             "ack": "false",
             "autoCreate": "false",
             "stateName": "",
             "role": "",
             "payloadType": "",
             "readonly": "",
             "stateUnit": "",
             "stateMin": "",
             "stateMax": "",
             "x": 680,
             "y": 100,
             "wires": []
         },
         {
             "id": "905eccb6718c33b1",
             "type": "change",
             "z": "30f50cdc81f34302",
             "name": "send to SQL Adapter",
             "rules": [
                 {
                     "t": "set",
                     "p": "sendTo",
                     "pt": "msg",
                     "to": "{\"adapter\":\"sql.0\",\"command\":\"query\",\"message\":\"\",\"result\":\"0_userdata.0.mwhelper.result\"}",
                     "tot": "json"
                 },
                 {
                     "t": "move",
                     "p": "payload",
                     "pt": "msg",
                     "to": "sendTo.message",
                     "tot": "msg"
                 },
                 {
                     "t": "move",
                     "p": "sendTo",
                     "pt": "msg",
                     "to": "payload",
                     "tot": "msg"
                 }
             ],
             "action": "",
             "property": "",
             "from": "",
             "to": "",
             "reg": false,
             "x": 320,
             "y": 140,
             "wires": [
                 [
                     "7d4d17c1c3e3505e",
                     "d57ea069d151e7b0",
                     "40233502982b276a"
                 ]
             ]
         },
         {
             "id": "e43c264b5f15ecb0",
             "type": "debug",
             "z": "30f50cdc81f34302",
             "name": "SQL result",
             "active": true,
             "tosidebar": true,
             "console": false,
             "tostatus": false,
             "complete": "payload",
             "targetType": "msg",
             "statusVal": "",
             "statusType": "auto",
             "x": 1070,
             "y": 160,
             "wires": []
         },
         {
             "id": "d57ea069d151e7b0",
             "type": "delay",
             "z": "30f50cdc81f34302",
             "name": "",
             "pauseType": "delay",
             "timeout": "250",
             "timeoutUnits": "milliseconds",
             "rate": "1",
             "nbRateUnits": "1",
             "rateUnits": "second",
             "randomFirst": "1",
             "randomLast": "5",
             "randomUnits": "seconds",
             "drop": false,
             "allowrate": false,
             "outputs": 1,
             "x": 580,
             "y": 160,
             "wires": [
                 [
                     "b811d795d4530384"
                 ]
             ]
         },
         {
             "id": "b811d795d4530384",
             "type": "ioBroker get",
             "z": "30f50cdc81f34302",
             "name": "result",
             "topic": "0_userdata.0.mwhelper.result",
             "attrname": "payload",
             "payloadType": "value",
             "errOnInvalidState": "nothing",
             "x": 770,
             "y": 160,
             "wires": [
                 [
                     "c39ef769f6c3a5ce"
                 ]
             ]
         },
         {
             "id": "c39ef769f6c3a5ce",
             "type": "json",
             "z": "30f50cdc81f34302",
             "name": "",
             "property": "payload",
             "action": "",
             "pretty": false,
             "x": 910,
             "y": 160,
             "wires": [
                 [
                     "e43c264b5f15ecb0"
                 ]
             ]
         },
         {
             "id": "89d24fa9dae59aa1",
             "type": "change",
             "z": "30f50cdc81f34302",
             "name": "send to MQTT Adapter",
             "rules": [
                 {
                     "t": "set",
                     "p": "sendTo",
                     "pt": "msg",
                     "to": "{\"adapter\":\"mqtt.1\",\"command\":\"sendMessage2Client\"}",
                     "tot": "json"
                 },
                 {
                     "t": "move",
                     "p": "payload",
                     "pt": "msg",
                     "to": "sendTo.message",
                     "tot": "msg"
                 },
                 {
                     "t": "move",
                     "p": "sendTo",
                     "pt": "msg",
                     "to": "payload",
                     "tot": "msg"
                 }
             ],
             "action": "",
             "property": "",
             "from": "",
             "to": "",
             "reg": false,
             "x": 380,
             "y": 440,
             "wires": [
                 [
                     "c869e86385c28208",
                     "eefe9b5106617c53"
                 ]
             ]
         },
         {
             "id": "64b709dff7660a6f",
             "type": "ioBroker out",
             "z": "30f50cdc81f34302",
             "name": "sendTo",
             "topic": "0_userdata.0.NodeRed.sendTo",
             "ack": "false",
             "autoCreate": "false",
             "stateName": "",
             "role": "",
             "payloadType": "",
             "readonly": "",
             "stateUnit": "",
             "stateMin": "",
             "stateMax": "",
             "x": 740,
             "y": 440,
             "wires": []
         },
         {
             "id": "66308db5f4cf558c",
             "type": "inject",
             "z": "30f50cdc81f34302",
             "name": "Publish mqtt topic",
             "props": [
                 {
                     "p": "payload"
                 }
             ],
             "repeat": "",
             "crontab": "",
             "once": false,
             "onceDelay": 0.1,
             "topic": "",
             "payload": "{\"topic\":\"your/topic/here2\",\"message\":\"Testnachricht\"}",
             "payloadType": "json",
             "x": 150,
             "y": 440,
             "wires": [
                 [
                     "89d24fa9dae59aa1"
                 ]
             ]
         },
         {
             "id": "165dc0884f716439",
             "type": "debug",
             "z": "30f50cdc81f34302",
             "name": "MQTT topic",
             "active": true,
             "tosidebar": true,
             "console": false,
             "tostatus": false,
             "complete": "payload",
             "targetType": "msg",
             "statusVal": "",
             "statusType": "auto",
             "x": 370,
             "y": 480,
             "wires": []
         },
         {
             "id": "7d4d17c1c3e3505e",
             "type": "json",
             "z": "30f50cdc81f34302",
             "name": "",
             "property": "payload",
             "action": "",
             "pretty": false,
             "x": 530,
             "y": 100,
             "wires": [
                 [
                     "fd62cf142cca7aec"
                 ]
             ]
         },
         {
             "id": "c869e86385c28208",
             "type": "json",
             "z": "30f50cdc81f34302",
             "name": "",
             "property": "payload",
             "action": "",
             "pretty": false,
             "x": 590,
             "y": 440,
             "wires": [
                 [
                     "64b709dff7660a6f"
                 ]
             ]
         },
         {
             "id": "c610499ae23a8d3d",
             "type": "comment",
             "z": "30f50cdc81f34302",
             "name": "Abfrage über den iobroker SQL Adapter",
             "info": "",
             "x": 210,
             "y": 40,
             "wires": []
         },
         {
             "id": "e33198f610486456",
             "type": "comment",
             "z": "30f50cdc81f34302",
             "name": "Abfrage über den iobroker MQTT Adapter",
             "info": "",
             "x": 220,
             "y": 380,
             "wires": []
         },
         {
             "id": "eefe9b5106617c53",
             "type": "debug",
             "z": "30f50cdc81f34302",
             "name": "sendTo",
             "active": true,
             "tosidebar": true,
             "console": false,
             "tostatus": false,
             "complete": "payload",
             "targetType": "msg",
             "statusVal": "",
             "statusType": "auto",
             "x": 600,
             "y": 400,
             "wires": []
         },
         {
             "id": "a53a3929530a7a45",
             "type": "ioBroker in",
             "z": "30f50cdc81f34302",
             "name": "",
             "topic": "0_userdata.0.mwhelper.result",
             "payloadType": "value",
             "onlyack": "update",
             "func": "all",
             "gap": "",
             "fireOnStart": "false",
             "outFormat": "MQTT",
             "x": 180,
             "y": 260,
             "wires": [
                 [
                     "50cc942afbf9b4b6"
                 ]
             ]
         },
         {
             "id": "d10d14fa1999d81c",
             "type": "debug",
             "z": "30f50cdc81f34302",
             "name": "SQL Ergebnis, wenn fertig",
             "active": true,
             "tosidebar": true,
             "console": false,
             "tostatus": false,
             "complete": "payload",
             "targetType": "msg",
             "statusVal": "",
             "statusType": "auto",
             "x": 590,
             "y": 260,
             "wires": []
         },
         {
             "id": "50cc942afbf9b4b6",
             "type": "json",
             "z": "30f50cdc81f34302",
             "name": "",
             "property": "payload",
             "action": "",
             "pretty": false,
             "x": 390,
             "y": 260,
             "wires": [
                 [
                     "d10d14fa1999d81c"
                 ]
             ]
         },
         {
             "id": "40233502982b276a",
             "type": "debug",
             "z": "30f50cdc81f34302",
             "name": "sendTo",
             "active": true,
             "tosidebar": true,
             "console": false,
             "tostatus": false,
             "complete": "payload",
             "targetType": "msg",
             "statusVal": "",
             "statusType": "auto",
             "x": 540,
             "y": 60,
             "wires": []
         }
      ]
      

      Jeder Flow bzw. jedes Script, das ich hier poste implementiert jeder auf eigene Gefahr. Flows und Scripts können Fehler aufweisen und weder der Seitenbetreiber noch ich persönlich können hierfür haftbar gemacht werden. Das gleiche gilt für Empfehlungen aller Art.

      1 Antwort Letzte Antwort
      2
      • mickymM Offline
        mickymM Offline
        mickym
        Most Active
        schrieb am zuletzt editiert von
        #3

        Es empfiehlt sich im Übrigen den Datenpunkt zum Austausch als Typ JSON zu definieren:

        8061764e-d3c0-4e80-aa17-070b22b56ee1-image.png

        Damit kann man das Script natürlich dann ohne NodeRed schon mal vortesten. ;)

        Jeder Flow bzw. jedes Script, das ich hier poste implementiert jeder auf eigene Gefahr. Flows und Scripts können Fehler aufweisen und weder der Seitenbetreiber noch ich persönlich können hierfür haftbar gemacht werden. Das gleiche gilt für Empfehlungen aller Art.

        S 1 Antwort Letzte Antwort
        1
        • mickymM mickym

          Es empfiehlt sich im Übrigen den Datenpunkt zum Austausch als Typ JSON zu definieren:

          8061764e-d3c0-4e80-aa17-070b22b56ee1-image.png

          Damit kann man das Script natürlich dann ohne NodeRed schon mal vortesten. ;)

          S Offline
          S Offline
          Sineos
          schrieb am zuletzt editiert von Sineos
          #4

          @mickym Sehr elegante Lösung :+1:

          Ich habe Beispiele wo auch message leer sein kann. Dann rennt das Script auf Fehler. Habs mal so gelöst (Zeile 43):

          
          /**
          * Zweck:      Setzt für einen NodeRed Flow - SendTo Kommandos an verschiedene Adapter ab
          * Datum:      17.08.2022
          * Autor:      @mickym
          */
          
          // In die Variable exchangeWithNodeRed den Pfad des Datenpunktes auswählen, der als Trigger verwendet wird
          
          /*********************************************************************************************************
           *  In den Datenpunkt muss ein Objekt von Node Red mit folgenden Eigenschaften übergeben werden:
           *  {
              "adapter": <Adapterinstanz oder Adapter z.Bsp mqtt.0, sql.0>,
              "command": <Kommando - hängt vom jeweilige Adapter ab - bei sql zum Beispiel query, bei manchen Adaptern auch nicht erforderlich>,
              "message": <Nachricht, die an den Adapter geschickt wird>,
              "result": <optional: Pfad zum Datenpunkt, wo das Ergebnis als String abgespeichert wird, ansonsten wird der Trigger als Ausgabepunkt verwendet>
              }
           *
           *
          */
          
          const exchangeWithNodeRed = '0_userdata.0.NodeRed.sendTo';
          
          on({id: exchangeWithNodeRed, change: 'any', ack: false}, function(obj) {
            console.log(obj.state.val);
            const val = JSON.parse(obj.state.val);
            let returnResult;
            //console.log('adapter: ' + val.adapter);
            //console.log('command: ' + val.command);
            //console.log('message: ' + val.message);
            //console.log('result: ' + val.result);
          
            if (!val.result) returnResult = exchangeWithNodeRed;
            else returnResult = val.result;
            if (!val.command){
              //console.log('no command');
              sendTo(val.adapter, val.message, function(result) {
                if (result.error) setState(returnResult, result.error, true); 
                else setState(returnResult, JSON.stringify(result.result), true);
              });
            } else {
              //console.log('command: ' + val.command);
              sendTo(val.adapter, val.command, val.message? val.message : {}, function(result) {
                if (result.error) setState(returnResult, result.error, true);
                else setState(returnResult, JSON.stringify(result.result), true);
              });
            }
          });
          
          
          mickymM 1 Antwort Letzte Antwort
          0
          • S Sineos

            @mickym Sehr elegante Lösung :+1:

            Ich habe Beispiele wo auch message leer sein kann. Dann rennt das Script auf Fehler. Habs mal so gelöst (Zeile 43):

            
            /**
            * Zweck:      Setzt für einen NodeRed Flow - SendTo Kommandos an verschiedene Adapter ab
            * Datum:      17.08.2022
            * Autor:      @mickym
            */
            
            // In die Variable exchangeWithNodeRed den Pfad des Datenpunktes auswählen, der als Trigger verwendet wird
            
            /*********************************************************************************************************
             *  In den Datenpunkt muss ein Objekt von Node Red mit folgenden Eigenschaften übergeben werden:
             *  {
                "adapter": <Adapterinstanz oder Adapter z.Bsp mqtt.0, sql.0>,
                "command": <Kommando - hängt vom jeweilige Adapter ab - bei sql zum Beispiel query, bei manchen Adaptern auch nicht erforderlich>,
                "message": <Nachricht, die an den Adapter geschickt wird>,
                "result": <optional: Pfad zum Datenpunkt, wo das Ergebnis als String abgespeichert wird, ansonsten wird der Trigger als Ausgabepunkt verwendet>
                }
             *
             *
            */
            
            const exchangeWithNodeRed = '0_userdata.0.NodeRed.sendTo';
            
            on({id: exchangeWithNodeRed, change: 'any', ack: false}, function(obj) {
              console.log(obj.state.val);
              const val = JSON.parse(obj.state.val);
              let returnResult;
              //console.log('adapter: ' + val.adapter);
              //console.log('command: ' + val.command);
              //console.log('message: ' + val.message);
              //console.log('result: ' + val.result);
            
              if (!val.result) returnResult = exchangeWithNodeRed;
              else returnResult = val.result;
              if (!val.command){
                //console.log('no command');
                sendTo(val.adapter, val.message, function(result) {
                  if (result.error) setState(returnResult, result.error, true); 
                  else setState(returnResult, JSON.stringify(result.result), true);
                });
              } else {
                //console.log('command: ' + val.command);
                sendTo(val.adapter, val.command, val.message? val.message : {}, function(result) {
                  if (result.error) setState(returnResult, result.error, true);
                  else setState(returnResult, JSON.stringify(result.result), true);
                });
              }
            });
            
            
            mickymM Offline
            mickymM Offline
            mickym
            Most Active
            schrieb am zuletzt editiert von
            #5

            @sineos Aha ;) - Muss dass dann ein leeres Objekt sein oder kann es auch ein leerer String sein? - nur halt nicht undefined nehme ich mal an.

            Jeder Flow bzw. jedes Script, das ich hier poste implementiert jeder auf eigene Gefahr. Flows und Scripts können Fehler aufweisen und weder der Seitenbetreiber noch ich persönlich können hierfür haftbar gemacht werden. Das gleiche gilt für Empfehlungen aller Art.

            S 1 Antwort Letzte Antwort
            0
            • mickymM mickym

              @sineos Aha ;) - Muss dass dann ein leeres Objekt sein oder kann es auch ein leerer String sein? - nur halt nicht undefined nehme ich mal an.

              S Offline
              S Offline
              Sineos
              schrieb am zuletzt editiert von
              #6

              @mickym Das ist wohl ein bisschen abhängig davon, was der Adapter erwartet. Die homematic rssiInfo Methode erwartet ein Objekt.

              mickymM 1 Antwort Letzte Antwort
              0
              • S Sineos

                @mickym Das ist wohl ein bisschen abhängig davon, was der Adapter erwartet. Die homematic rssiInfo Methode erwartet ein Objekt.

                mickymM Offline
                mickymM Offline
                mickym
                Most Active
                schrieb am zuletzt editiert von
                #7

                @sineos Dann würde ich aber nicht den JS Code ändern, sondern belassen und aus NodeRed ein leeres Objekt als message mitgeben.

                Jeder Flow bzw. jedes Script, das ich hier poste implementiert jeder auf eigene Gefahr. Flows und Scripts können Fehler aufweisen und weder der Seitenbetreiber noch ich persönlich können hierfür haftbar gemacht werden. Das gleiche gilt für Empfehlungen aller Art.

                S 1 Antwort Letzte Antwort
                0
                • mickymM mickym

                  @sineos Dann würde ich aber nicht den JS Code ändern, sondern belassen und aus NodeRed ein leeres Objekt als message mitgeben.

                  S Offline
                  S Offline
                  Sineos
                  schrieb am zuletzt editiert von
                  #8

                  @mickym Stimmt, auch ne Möglichkeit. Sogar die flexiblere. :+1:

                  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

                  808

                  Online

                  32.5k

                  Benutzer

                  81.6k

                  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