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. JavaScript
  5. Modulare Skripe

NEWS

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

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.2k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.3k

Modulare Skripe

Geplant Angeheftet Gesperrt Verschoben JavaScript
javascript
13 Beiträge 6 Kommentatoren 1.9k Aufrufe 5 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.
  • A Offline
    A Offline
    azamir
    schrieb am zuletzt editiert von
    #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 Antworten Letzte Antwort
    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
      schrieb am zuletzt editiert von 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 Antwort Letzte Antwort
      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
        schrieb am zuletzt editiert von
        #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 Antwort Letzte Antwort
        0
        • N Offline
          N Offline
          Nahasapee
          schrieb am zuletzt editiert von
          #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 Antwort Letzte Antwort
          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
            schrieb am zuletzt editiert von
            #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 Antwort Letzte Antwort
            0
            • HomoranH Nicht stören
              HomoranH Nicht stören
              Homoran
              Global Moderator Administrators
              schrieb am zuletzt editiert von
              #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 - es gibt fast nichts, was nicht auch für andere interessant ist.

              Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

              der Installationsfixer: curl -fsL https://iobroker.net/fix.sh | bash -

              AlCalzoneA 1 Antwort Letzte Antwort
              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
                schrieb am zuletzt editiert von
                #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 Antwort Letzte Antwort
                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 Nicht stören
                  HomoranH Nicht stören
                  Homoran
                  Global Moderator Administrators
                  schrieb am zuletzt editiert von
                  #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 - es gibt fast nichts, was nicht auch für andere interessant ist.

                  Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

                  der Installationsfixer: curl -fsL https://iobroker.net/fix.sh | bash -

                  1 Antwort Letzte Antwort
                  0
                  • Z Offline
                    Z Offline
                    zerraxys
                    schrieb am zuletzt editiert von
                    #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 Antwort Letzte Antwort
                    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
                      schrieb am zuletzt editiert von
                      #10

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

                      Z 1 Antwort Letzte Antwort
                      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
                        schrieb am zuletzt editiert von
                        #11

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

                        1 Antwort Letzte Antwort
                        0
                        • A Offline
                          A Offline
                          azamir
                          schrieb am zuletzt editiert von
                          #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 Antwort Letzte Antwort
                          0
                          • A azamir

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

                            Z Offline
                            Z Offline
                            zerraxys
                            schrieb am zuletzt editiert von
                            #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 Antwort Letzte Antwort
                            1
                            Antworten
                            • In einem neuen Thema antworten
                            Anmelden zum Antworten
                            • Älteste zuerst
                            • Neuste zuerst
                            • Meiste Stimmen


                            Support us

                            ioBroker
                            Community Adapters
                            Donate

                            439

                            Online

                            32.4k

                            Benutzer

                            81.5k

                            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