NEWS


  • 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

  • Developer

    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 */);
    
  • Forum Testing Most Active Global Moderator Administrators

    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
  • Developer

    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("...")).

  • Forum Testing Most Active Global Moderator Administrators

    AlCalzone sagte in Modulare Skripe:

    Die Essenz steht direkt über deinem Post

    Hab ich fast befürchtet 😢

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


  • 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.

  • Starter

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

  • Starter

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

  • Starter

    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!


  • 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.

Suggested Topics

1.8k
Online

34.6k
Users

40.7k
Topics

557.8k
Posts