Skip to content
  • Home
  • Recent
  • Tags
  • 0 Unread 0
  • Categories
  • Unreplied
  • Popular
  • 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

  • Default (No Skin)
  • No Skin
Collapse
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. Modulare Skripe

NEWS

  • Monatsrückblick Januar/Februar 2026 ist online!
    BluefoxB
    Bluefox
    17
    1
    541

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    17
    1
    5.4k

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    13
    1
    1.4k

Modulare Skripe

Scheduled Pinned Locked Moved JavaScript
javascript
13 Posts 6 Posters 2.1k Views 5 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    azamir
    wrote on last edited by
    #1

    Hallo alle!

    Meine Skriptsammlung ist mittlerweile recht groß und ich würde sie gerne in Modulen verwalten. Ein Modul soll hierbei folgendes können

    • Persistenten Zustand haben (zumindest bis zum Adapter-Neustart)
    • Interne Datenstrukturen kapseln und vor dem "Nutzer" verstecken
    • Nur bestimmte Funktionalität für andere Module und Skripte anbieten
    • Eigene subscriptions/schedules für die interne Funktionalität haben

    Ein Modul sieht bei mir so aus:

    const someModule = function() {
      const internaldata1 = {
      };
      
      // ...
    
      doSomeFancyInitialization();
      on("x", ...)
      on("x", ...)
    
      // ...
    
      return {
        function1() {
        },
        function2() {
        }
      }
    }();
    

    Nun habe ich die Möglichkeit, dieses Modul entweder Global oder als normales Skript zu speichern und beides ist mit Problemen behaftet:

    • Als normales Skript sind someModule.function1 und someModule.function2 nicht von anderen Skripten erreichbar
    • Als globales Skript hat jedes normale Skript eine eigene Instanz des Moduls (Code wird einfach "davor" gehangen) und ich habe keinen zentralen State

    Folgendes kam mir in den Sinn, ich hätte hier aber gerne die Meinung der Experten:

    • Alle internen Daten als Datenpunkte speichern und alle Modulinstanzen subscriben sich darauf um ihren internen Zustand synchron zu halten
      • Bekommt man dann alles synchron? Ich könnte mir vorstellen dass das eine komplexe Aufgabe ist
    • Alle Module als echte node-Module direkt in node_modules speichern
      • Kann ich dann aus meinen Modulen heraus die ioBroker-Funktionen getState etc. nutzen?

    Für Input bin ich sehr dankbar!

    paul53P AlCalzoneA 2 Replies Last reply
    0
    • A azamir

      Hallo alle!

      Meine Skriptsammlung ist mittlerweile recht groß und ich würde sie gerne in Modulen verwalten. Ein Modul soll hierbei folgendes können

      • Persistenten Zustand haben (zumindest bis zum Adapter-Neustart)
      • Interne Datenstrukturen kapseln und vor dem "Nutzer" verstecken
      • Nur bestimmte Funktionalität für andere Module und Skripte anbieten
      • Eigene subscriptions/schedules für die interne Funktionalität haben

      Ein Modul sieht bei mir so aus:

      const someModule = function() {
        const internaldata1 = {
        };
        
        // ...
      
        doSomeFancyInitialization();
        on("x", ...)
        on("x", ...)
      
        // ...
      
        return {
          function1() {
          },
          function2() {
          }
        }
      }();
      

      Nun habe ich die Möglichkeit, dieses Modul entweder Global oder als normales Skript zu speichern und beides ist mit Problemen behaftet:

      • Als normales Skript sind someModule.function1 und someModule.function2 nicht von anderen Skripten erreichbar
      • Als globales Skript hat jedes normale Skript eine eigene Instanz des Moduls (Code wird einfach "davor" gehangen) und ich habe keinen zentralen State

      Folgendes kam mir in den Sinn, ich hätte hier aber gerne die Meinung der Experten:

      • Alle internen Daten als Datenpunkte speichern und alle Modulinstanzen subscriben sich darauf um ihren internen Zustand synchron zu halten
        • Bekommt man dann alles synchron? Ich könnte mir vorstellen dass das eine komplexe Aufgabe ist
      • Alle Module als echte node-Module direkt in node_modules speichern
        • Kann ich dann aus meinen Modulen heraus die ioBroker-Funktionen getState etc. nutzen?

      Für Input bin ich sehr dankbar!

      paul53P Offline
      paul53P Offline
      paul53
      wrote on last edited by paul53
      #2

      @azamir sagte in Modulare Skripe:

      Kann ich dann aus meinen Modulen heraus die ioBroker-Funktionen getState etc. nutzen?

      Nein, habe es gerade getestet mit folgendem Modul test.js:

      'use strict';
      module.exports = function (id) {
         return getState(id);
      };
      

      mit diesem Aufruf

      const test = require('../../../iobroker-data/modules/test.js');
      
      log(test('javascript.1.test.array1'));
      

      erhalte ich folgende Fehlermeldungen:

      javascript.1	2019-12-21 19:50:19.705	error	(6331) at module.exports (/opt/iobroker/iobroker-data/modules/test.js:3:4)
      javascript.1	2019-12-21 19:50:19.705	error	(6331) ReferenceError: getState is not defined
      

      Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
      Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

      A 1 Reply Last reply
      0
      • paul53P paul53

        @azamir sagte in Modulare Skripe:

        Kann ich dann aus meinen Modulen heraus die ioBroker-Funktionen getState etc. nutzen?

        Nein, habe es gerade getestet mit folgendem Modul test.js:

        'use strict';
        module.exports = function (id) {
           return getState(id);
        };
        

        mit diesem Aufruf

        const test = require('../../../iobroker-data/modules/test.js');
        
        log(test('javascript.1.test.array1'));
        

        erhalte ich folgende Fehlermeldungen:

        javascript.1	2019-12-21 19:50:19.705	error	(6331) at module.exports (/opt/iobroker/iobroker-data/modules/test.js:3:4)
        javascript.1	2019-12-21 19:50:19.705	error	(6331) ReferenceError: getState is not defined
        
        A Offline
        A Offline
        azamir
        wrote on last edited by
        #3

        @paul53 Vielen Dank für den schnellen Test. Ich habe selber noch keine Node-Module geschrieben. Hätte ich gewusst dass das so einfach ist, hätte ich es auch selber tun können :blush: Sorry

        Vielleicht wird getState ja von irgendeinem Modul zur Verfügung gestellt, das man wiederum in seinem Modul per require einbinden muss (und hoffentlich kann)?

        1 Reply Last reply
        0
        • N Offline
          N Offline
          Nahasapee
          wrote on last edited by
          #4

          Hi, also
          was du hier vor hast habe ich in meinen telegram npm paket indirekt eigentlich umgesetzt,
          das nutze ich um dynamisch Menüs in Telegram zu generieren

          Ich übergebe im JavaScript -Adapter in einem initialen javascript einfach an meinem NPM Paket die JavaScript Instanz
          und habe dann im Modul vollen Zugriff auf alle iobroker funktionen
          Um das jetzt der korrekte weg ist kann ich dir aber nicht sagen.
          wie ich das umgesetzt habe kannst du hier schauen :

          https://github.com/Nahasapeemapetilon/MyTelegramMenu
          viele grüße

          A 1 Reply Last reply
          0
          • A azamir

            Hallo alle!

            Meine Skriptsammlung ist mittlerweile recht groß und ich würde sie gerne in Modulen verwalten. Ein Modul soll hierbei folgendes können

            • Persistenten Zustand haben (zumindest bis zum Adapter-Neustart)
            • Interne Datenstrukturen kapseln und vor dem "Nutzer" verstecken
            • Nur bestimmte Funktionalität für andere Module und Skripte anbieten
            • Eigene subscriptions/schedules für die interne Funktionalität haben

            Ein Modul sieht bei mir so aus:

            const someModule = function() {
              const internaldata1 = {
              };
              
              // ...
            
              doSomeFancyInitialization();
              on("x", ...)
              on("x", ...)
            
              // ...
            
              return {
                function1() {
                },
                function2() {
                }
              }
            }();
            

            Nun habe ich die Möglichkeit, dieses Modul entweder Global oder als normales Skript zu speichern und beides ist mit Problemen behaftet:

            • Als normales Skript sind someModule.function1 und someModule.function2 nicht von anderen Skripten erreichbar
            • Als globales Skript hat jedes normale Skript eine eigene Instanz des Moduls (Code wird einfach "davor" gehangen) und ich habe keinen zentralen State

            Folgendes kam mir in den Sinn, ich hätte hier aber gerne die Meinung der Experten:

            • Alle internen Daten als Datenpunkte speichern und alle Modulinstanzen subscriben sich darauf um ihren internen Zustand synchron zu halten
              • Bekommt man dann alles synchron? Ich könnte mir vorstellen dass das eine komplexe Aufgabe ist
            • Alle Module als echte node-Module direkt in node_modules speichern
              • Kann ich dann aus meinen Modulen heraus die ioBroker-Funktionen getState etc. nutzen?

            Für Input bin ich sehr dankbar!

            AlCalzoneA Offline
            AlCalzoneA Offline
            AlCalzone
            Developer
            wrote on last edited by
            #5

            @azamir sagte in Modulare Skripe:

            Kann ich dann aus meinen Modulen heraus die ioBroker-Funktionen getState etc. nutzen?

            Nur wenn du deine Module jeweils in eine Funktion kapselst, der du diese Funktionen beim Laden übergibst, etwa so:

            // modul.js
            module.exports = function(getState, ... /* weitere benötigte Funktionen */) {
              // hier der Modul-Code
            }
            
            // skript.js
            const modul = require("../pfad/zum/modul.js")(getState, ... /* weitere benötigte Funktionen */);
            

            Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

            1 Reply Last reply
            0
            • HomoranH Do not disturb
              HomoranH Do not disturb
              Homoran
              Global Moderator Administrators
              wrote on last edited by
              #6

              Ich möchte den Thread nicht kapern, wollte selber einen solchen eröffnen.
              Habe vom scripten leider viel zu wenig Ahnung und wollte für die Nutzung von tts via sonos ein "Modul" schreiben, dem man irgendwie bei anderen Aufrufen einige Parameter übergeben kann.
              Deswegen habe ich die Variablen verwendet.

              https://github.com/Homoran/iobroker.sonos_api#beispiel-fenster-offen-meldung

              Der untere Teil mit der Übergabe an die Sonos api sollte ein "Modul" werden.

              Wie kann man so etwas verwenden

              • "Modul" sichern
              • Werte durch ein anderes Skript übergeben und das Modul aufrufen

              kein Support per PN! - Fragen im Forum stellen -
              Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.
              Das Forum freut sich über eine Spende. Benutzt dazu den Spendenbutton im Header. Danke!
              der Installationsfixer: curl -fsL https://iobroker.net/fix.sh | bash -

              AlCalzoneA 1 Reply Last reply
              0
              • HomoranH Homoran

                Ich möchte den Thread nicht kapern, wollte selber einen solchen eröffnen.
                Habe vom scripten leider viel zu wenig Ahnung und wollte für die Nutzung von tts via sonos ein "Modul" schreiben, dem man irgendwie bei anderen Aufrufen einige Parameter übergeben kann.
                Deswegen habe ich die Variablen verwendet.

                https://github.com/Homoran/iobroker.sonos_api#beispiel-fenster-offen-meldung

                Der untere Teil mit der Übergabe an die Sonos api sollte ein "Modul" werden.

                Wie kann man so etwas verwenden

                • "Modul" sichern
                • Werte durch ein anderes Skript übergeben und das Modul aufrufen
                AlCalzoneA Offline
                AlCalzoneA Offline
                AlCalzone
                Developer
                wrote on last edited by
                #7

                @Homoran sagte in Modulare Skripe:

                Werte durch ein anderes Skript übergeben und das Modul aufrufen

                Die Essenz steht direkt über deinem Post ;) Der Trick liegt im Export einer Funktion sowie dem Aufrufen dieser Funktion beim Laden (Klammern hinter require("...")).

                Warum `sudo` böse ist: https://forum.iobroker.net/post/17109

                HomoranH 1 Reply Last reply
                0
                • AlCalzoneA AlCalzone

                  @Homoran sagte in Modulare Skripe:

                  Werte durch ein anderes Skript übergeben und das Modul aufrufen

                  Die Essenz steht direkt über deinem Post ;) Der Trick liegt im Export einer Funktion sowie dem Aufrufen dieser Funktion beim Laden (Klammern hinter require("...")).

                  HomoranH Do not disturb
                  HomoranH Do not disturb
                  Homoran
                  Global Moderator Administrators
                  wrote on last edited by
                  #8

                  @AlCalzone sagte in Modulare Skripe:

                  Die Essenz steht direkt über deinem Post

                  Hab ich fast befürchtet :cry:

                  Dabrauche ich aber noch Jahrzehnte bis ich das verstehe - ich werde mich bemühen.

                  kein Support per PN! - Fragen im Forum stellen -
                  Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.
                  Das Forum freut sich über eine Spende. Benutzt dazu den Spendenbutton im Header. Danke!
                  der Installationsfixer: curl -fsL https://iobroker.net/fix.sh | bash -

                  1 Reply Last reply
                  0
                  • Z Offline
                    Z Offline
                    zerraxys
                    wrote on last edited by
                    #9

                    Ich stehe vor dem selben Problem und experimentiere gerade mit einer Lösung über eval (ich weiß, das ist eigentlich evil). Als globale Funktion habe ich ein load Skript, dass wir folgt aussieht

                    const loadCache = {};
                    function load (filename) {
                        if (!loadCache[filename]) {
                            const path = require("path");
                            const fs = require("fs");
                    
                            const fn = path.resolve("opt", "iobroker", "iobroker-scripts", "scripts", "Modules", filename) + ".js";
                            const source = fs.readFileSync(fn, "utf8");
                    
                            var module = {};
                            eval(source);
                            loadCache[filename] = module.exports;
                        }
                    
                        return loadCache[filename];
                    };
                    
                    

                    In meinen Skripten kann ich miit einem einfachen

                    var meinModul = load("mein_modul");
                    

                    die Datei /opt/iobroker/iobroker-scripts/scripts/Modules/mein_modul.js laden und deren "module.exports"-Wert bekommen. Offene Ideen sind im Moment noch:

                    • Das globale require überladen, damit es natürlicher aussieht
                    • Den Pfad irgendwie zur Laufzeit bestimmen, damit er nicht hart eingebrannt ist

                    Aber zumindest läuft es erstmal und ich kann anfangen, etwas Ordnung zu schaffen.

                    A 1 Reply Last reply
                    0
                    • Z zerraxys

                      Ich stehe vor dem selben Problem und experimentiere gerade mit einer Lösung über eval (ich weiß, das ist eigentlich evil). Als globale Funktion habe ich ein load Skript, dass wir folgt aussieht

                      const loadCache = {};
                      function load (filename) {
                          if (!loadCache[filename]) {
                              const path = require("path");
                              const fs = require("fs");
                      
                              const fn = path.resolve("opt", "iobroker", "iobroker-scripts", "scripts", "Modules", filename) + ".js";
                              const source = fs.readFileSync(fn, "utf8");
                      
                              var module = {};
                              eval(source);
                              loadCache[filename] = module.exports;
                          }
                      
                          return loadCache[filename];
                      };
                      
                      

                      In meinen Skripten kann ich miit einem einfachen

                      var meinModul = load("mein_modul");
                      

                      die Datei /opt/iobroker/iobroker-scripts/scripts/Modules/mein_modul.js laden und deren "module.exports"-Wert bekommen. Offene Ideen sind im Moment noch:

                      • Das globale require überladen, damit es natürlicher aussieht
                      • Den Pfad irgendwie zur Laufzeit bestimmen, damit er nicht hart eingebrannt ist

                      Aber zumindest läuft es erstmal und ich kann anfangen, etwas Ordnung zu schaffen.

                      A Offline
                      A Offline
                      azamir
                      wrote on last edited by
                      #10

                      @zerraxys Bedeutet das dann aber nicht, dass der loadCache in jeden Skript einzeln gefüllt wird?

                      Z 1 Reply Last reply
                      0
                      • N Nahasapee

                        Hi, also
                        was du hier vor hast habe ich in meinen telegram npm paket indirekt eigentlich umgesetzt,
                        das nutze ich um dynamisch Menüs in Telegram zu generieren

                        Ich übergebe im JavaScript -Adapter in einem initialen javascript einfach an meinem NPM Paket die JavaScript Instanz
                        und habe dann im Modul vollen Zugriff auf alle iobroker funktionen
                        Um das jetzt der korrekte weg ist kann ich dir aber nicht sagen.
                        wie ich das umgesetzt habe kannst du hier schauen :

                        https://github.com/Nahasapeemapetilon/MyTelegramMenu
                        viele grüße

                        A Offline
                        A Offline
                        azamir
                        wrote on last edited by
                        #11

                        @Nahasapee Vielen Dank, ich schaue mir das mal genauer an und poste dann hier meine Erkenntnisse und was ich daraus gemacht habe.

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          azamir
                          wrote on last edited by
                          #12

                          Ich habe ein bisschen rumprobiert und folgendes getan:

                          • Verzeichnis /opt/iobroker/node_modules/ioBroker.javascript/node_modules/mymodules angelegt
                          • npm init darin ausgeführt
                          • Folgendes in die index.js geschrieben
                          let modules = {};
                          let instance = null;
                          let initialized = null;
                          
                          // above only boilerplate code
                          
                          modules.inspect = function() {
                                  return {
                                          initialized() {
                                                  return initialized;
                                          },
                                          instance() {
                                                  return instance;
                                          }
                                  }
                          }()
                          
                          // below only boilerplate code
                          
                          module.exports = function(js_instance) {
                                  if (!instance) {
                                          console.log("Initializing modules");
                                          initialized = new Date();
                                          instance = js_instance;
                                  }
                                  return modules;
                          }
                          
                          • mymodules in der Adapterkonfiguration zu den benötigten Modulen hinzugefügt
                          • Um zu prüfen, ob meine Datenstrukturen auch wirklich nur einmal initialisiert werden, habe ich zwei identische Skripte mit folgendem Inhalt angelegt:
                          const mymodules = require('mymodules')(this);
                          console.log(mymodules.inspect.initialized());
                          

                          Beide Skripte geben den gleichen Zeitstempel aus, wodurch ich davon ausgehe dass die Initialisierung tatsächlich nur einmal stattgefunden hat. Ich kann nun (und man möge mich bitte korrigieren wenn ich einen Denkfehler gemacht habe!) an beliebigen Stellen in meinen Skripten - vorzugsweise am Anfang wo this noch ganz eindeutig definiert ist - mit einem

                          const mymodules = require('mymodules')(this);
                          

                          auf meine Module zugreifen

                          Nächste Schritte:

                          • Module selber auch wieder per require in das "Obermodul" einbinden
                          • Irgendwie so hosten, dass ich bequeme Versionsverwaltung habe aber es trotzdem nicht öffentlich machen muss (Hat jemand eine Idee?)

                          Danke für eure guten Ideen und ich bin immer offen für Verbesserungsvorschläge!

                          1 Reply Last reply
                          0
                          • A azamir

                            @zerraxys Bedeutet das dann aber nicht, dass der loadCache in jeden Skript einzeln gefüllt wird?

                            Z Offline
                            Z Offline
                            zerraxys
                            wrote on last edited by
                            #13

                            @azamir Ja, ich denke das ist der Fall. Aber Skripte laufen doch auch so unabhängig voneinander. Ich wüsste nicht, wie man Daten zwischen denen teilen kann.

                            1 Reply Last reply
                            1
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            Support us

                            ioBroker
                            Community Adapters
                            Donate

                            342

                            Online

                            32.7k

                            Users

                            82.5k

                            Topics

                            1.3m

                            Posts
                            Community
                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                            ioBroker Community 2014-2025
                            logo
                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Home
                            • Recent
                            • Tags
                            • Unread 0
                            • Categories
                            • Unreplied
                            • Popular
                            • GitHub
                            • Docu
                            • Hilfe