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. Entwicklung
  4. [Frage] 'adapter' funktionen nicht überall verfügbar

NEWS

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

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

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    25
    1
    2.4k

[Frage] 'adapter' funktionen nicht überall verfügbar

Geplant Angeheftet Gesperrt Verschoben Entwicklung
8 Beiträge 4 Kommentatoren 1.5k Aufrufe
  • Ä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.
  • Jey CeeJ Online
    Jey CeeJ Online
    Jey Cee
    Developer
    schrieb am zuletzt editiert von
    #1

    Hallo zusammen,

    um den code des Adapters etwas übersichtlicher zu halten habe ich mir ein zusätzliches Modul erstellt, welches im Unterordner 'lib' abgelegt ist. Leider lassen sich nicht alle 'adapter' Funktionen von dort ausführen.

    adapter.setObject
    ````Funktioniert einwandfrei.
    
    EDIT:````
    adapter.getObject
    ````Geht auch.
    
    

    adapter.getState

    
    

    [TypeError: adapter.getState is not a function]

    
    Stellt sich die Frage ist das bekannt und so gewollt oder muss hier anders vorgegangen werden?

    Persönlicher Support
    Spenden -> paypal.me/J3YC33

    1 Antwort Letzte Antwort
    0
    • AlCalzoneA Offline
      AlCalzoneA Offline
      AlCalzone
      Developer
      schrieb am zuletzt editiert von
      #2

      Ich hab das im tradfri-Adapter so gelöst (Code etwas vereinfacht):

      Im Ordner lib ein Modul "global" erstellt:

      // Singleton-Pattern
      let __instance = null;
      
      class Global {
      
      	constructor() {
      		if (__instance) {
      			return __instance;
      		}
      		__instance = this;
      	}
      
      	get adapter() { return this._adapter; }
      	set adapter(adapter) {
      		this._adapter = adapter;
      		// [...] Adapter-Objekt um eine Handvoll promisifizierte Funktionen ergänzt
      	}
      
      	// [...] weitere Helferfunktionen
      }
      
      const stuff = new Global();
      export default stuff;
      

      Im Hauptteil des Programms muss die Variable einmal befüllt werden:

      import _ from "./lib/global";
      
      // [...]
      
      // Adapter-Objekt erstellen
      const adapter = utils.adapter({
      	name: "tradfri",
      
      	// Wird aufgerufen, wenn Adapter initialisiert wird
      	ready: function () {
      		// Adapter-Instanz global machen
      		_.adapter = adapter;
      		//...
      	}
      
      	// ...
      });
      
      

      Dann in allen Modulen, die auf adapter Zugriff benötigen:

      import _ from "./global";
      
      // Zugriff auf Adapter per
      _.adapter.getState
      _.adapter.setState
      // etc.
      
      

      Import und export ist ES6-Syntax, du solltest aber bei Google finden, wie sich das mit älterer Syntax darstellen lässt.

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

      1 Antwort Letzte Antwort
      0
      • apollon77A Offline
        apollon77A Offline
        apollon77
        schrieb am zuletzt editiert von
        #3

        Ich denke der saubere Weg ist dir die adapter-Instanz (also Variable "adapter") mit an die Funktionen in deinem Lib-File zu übergeben wo Du Sie brauchst.

        In "lib"-Files lagert man ja üblicherweise Funktionen aus die man dann aufruft.

        Wenn in lib eine Klasse liegt dann der Klasse beim Konstruktur übergeben und als eigene Skript-Variable ablegen. Dann kannst Du es verwenden.

        In JavaScript hat jedes .js File erstmal seinen eigenen Variablenscope …

        Beitrag hat geholfen? Votet rechts unten im Beitrag :-) https://paypal.me/Apollon77 / https://github.com/sponsors/Apollon77

        • Debug-Log für Instanz einschalten? Admin -> Instanzen -> Expertenmodus -> Instanz aufklappen - Loglevel ändern
        • Logfiles auf Platte /opt/iobroker/log/… nutzen, Admin schneidet Zeilen ab
        1 Antwort Letzte Antwort
        0
        • Jey CeeJ Online
          Jey CeeJ Online
          Jey Cee
          Developer
          schrieb am zuletzt editiert von
          #4

          Danke für die Antworten.

          Die Lösung von @apollon77 ist wirklich einfach, damit geht es.

          @apollon77:

          der Klasse beim Konstruktur übergeben `
          Kannst du mir das bitte anders erklären, ich glaube genau das gemacht zu haben was du mir damit sagen willst.

          Ich hab mir einfach eine Funktion gebaut die beim Start des Adapters die Variable 'adapter' in meine 'lib' an eine Variable übergibt.

          @AlCalzone: Deine Lösung übersteigt mein Verständnis, ich verstehe gerade mal Ansatzweise wie die Zusammenhänge sind.

          Abschließend bleibt die Frage warum ein Teil der Funktionen aus 'adapter' nicht verfügbar sind wenn ich sie mithilfe von````
          var utils = require(__dirname + '/utils');
          var adapter = utils.adapter('upnp');

          Persönlicher Support
          Spenden -> paypal.me/J3YC33

          1 Antwort Letzte Antwort
          0
          • AlCalzoneA Offline
            AlCalzoneA Offline
            AlCalzone
            Developer
            schrieb am zuletzt editiert von
            #5

            @Jey Cee: Im Prinzip wollte ich genau das vermeiden, was apollon77 vorgeschlagen hat. Der Ansatz stammt ursprünglich aus einem anderen Projekt, wo der Code in so viele verschiedene Komponenten aufgeteilt ist, dass ich zig bis hunderte Male die Adapter-Instanz übergeben müsste, teils von Komponente in Komponente in Komponente…

            Der Ansatz mal in einfachen Worten zusammengefasst:

            Im Modul /lib/global wird eine Klasse definiert, die als eine Eigenschaft die Adapter-Instanz (Inhalt der Variable "adapter" aus dem main-file) zugewiesen bekommt.

            ! Diese Klasse ist ein Singleton, d.h. egal wie oft sie per require/import eingebunden wird, wird immer auf das identische Objekt zugegriffen (das ist der Code am Anfang mit __instance). Wenn die Klasse erstmalig erstellt wird, wird ihr Verweis in __instance gespeichert. Bei zukünftigen Zugriffen wird sie nicht neu erstellt, sondern der Verweis in __instance stattdessen zurückgegeben.
            ! Das geht möglicherweise auch ohne dieses Singleton-Pattern, bin mir nicht 100% sicher, ob das bei require() eh nicht schon passiert.
            Diese Klasse wird zu Beginn jeder Code-Datei, die Zugriff auf die Adapter-Instanz benötigt, eingebunden und ihr der Variablenname _ zugewiesen (Schreibfaulheit). Das sollte auch per````
            var _ = require("./global");

            
            Im Main-Modul bei der Adapter-Erstellung wird diese Variable einmalig beschrieben, sodass anschließend jeder Verweis auf _.adapter auf die eigentliche Instanz zugreift.
            
              ` > ````
            > var adapter = utils.adapter('upnp');
            > ```` `  
            Ist das so gedacht, bzw. sollte das funktionieren? Ich dachte utils.adapter erstellt eine ****neue**** Adapter-Instanz und gibt diese zurück.

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

            1 Antwort Letzte Antwort
            0
            • Jey CeeJ Online
              Jey CeeJ Online
              Jey Cee
              Developer
              schrieb am zuletzt editiert von
              #6

              Ok jetzt versteh ich das besser. Danke für die gute Erklärung.

              @AlCalzone:

              CODE: ALLES AUSWÄHLEN

              var adapter = utils.adapter('upnp');

              Ist das so gedacht, bzw. sollte das funktionieren? Ich dachte utils.adapter erstellt eine neue Adapter-Instanz und gibt diese zurück. `
              Das ist eine Interessante Frage, daran merkt man halt das ich wenig Ahnung JavaScript/Node.js hab. Für mich war es immer nur ein Verweis auf eine Klasse/Funktionsbibliothek.

              Was ich jetzt weiss ist das utils.adapter definitiv die Instanz zurück gibt, aber daneben auch alle verfügbaren Funktionen die in der adapter.js festgelegt sind.

              Persönlicher Support
              Spenden -> paypal.me/J3YC33

              1 Antwort Letzte Antwort
              0
              • apollon77A Offline
                apollon77A Offline
                apollon77
                schrieb am zuletzt editiert von
                #7

                Ja, der code baut eine neue (zweite) Instanz. Würde ich also so nicht machen. Ob es wirklich ein Problem ist weiss ich aber auch nicht.

                Die Lösung von AlCazone geht auch. Am Ende ist es auch einfach eine Funktion "setAdapter" in deinem Lib-File die du dann über exports bekannt machst und aus dem hauptscript aufrufst und die nix anderes macht als

                var adapter;

                function setAdapter(adapt) {

                adapter=adapt;

                }

                Beitrag hat geholfen? Votet rechts unten im Beitrag :-) https://paypal.me/Apollon77 / https://github.com/sponsors/Apollon77

                • Debug-Log für Instanz einschalten? Admin -> Instanzen -> Expertenmodus -> Instanz aufklappen - Loglevel ändern
                • Logfiles auf Platte /opt/iobroker/log/… nutzen, Admin schneidet Zeilen ab
                1 Antwort Letzte Antwort
                0
                • carsten04C Online
                  carsten04C Online
                  carsten04
                  Developer
                  schrieb am zuletzt editiert von
                  #8

                  Ich finde beide Lösungen zur Sichtbarmachung des Adapter-Instanzobjektes adpater in eigenen Modulen haben Ihre Berechtigung. Die Lösung von AlCalzone finde ich sehr elegant, insbesondere dann, wenn ich das instanzierte Adapterobjekt noch dynamisch anpassen möchte (z.B. einige Methoden promisifizieren möchte, etc.). Dann kann ich das schön übersichtlich in global.js machen. Wenn ich nur adapter in wenigen eigenen Modulen benötige, mache ich es eigentlich immer so, wie von apollon77 vorgeschlagen. Das geht schnell und ist sehr überschaubar. Bei der Lösung von AlCalzone muss mann sich immer bewusst machen, dass Klassen erst ab Nodeversion 4.8.3 zur Verfügung stehen, dass eine Kompatibilität zur Nodeversion 0.12.18, die ja auch noch vielfach genutzt wird, nicht gegeben ist.

                  Im Umgang mit adapter sollte man auch wissen, dass mit

                  const utils = require(path.join(__dirname, '/lib/utils'));
                  var adapter = utils.adapter(options);
                  
                  

                  am Anfang von main.js die Erzeugung von adapter asynchron erfolgt. Dies liegt an dem Aufruf von

                  initObjects(callback);
                  
                  

                  innerhalb des Adapter-Konstruktors. Hierdurch werden im adapter alle Methoden in

                  adapter.objects
                  adapter.states
                  
                  

                  (in der Regel als ObjectsInMemClient und StatesInMemClient) für die Abstraktionsschicht zur Verfügung gestellt.

                  Das hat zur Folge, dass z.B. folgender Aufruf am Anfang von main.js

                  const Promise = require('bluebird');
                  
                  const utils = require(path.join(__dirname, '/lib/utils'));
                  var adapter = utils.adapter(options);
                  
                  adapter = Promise.promisifyAll(adapter);
                  
                  

                  nicht vollständig funktionieren muss, da adapter.states zu diesem Zeitpunkt noch nicht erzeugt wurde.

                  Man muss also immer das ready-Event abwarten, um Änderungen in adapter vorzunehmen, d.h. erst in main() ist wirklich sichergestellt, dass adapter vollständig zur Verfügung steht.

                  Grüße

                  Carsten

                  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

                  606

                  Online

                  32.6k

                  Benutzer

                  82.3k

                  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