NEWS
[Frage] Adapter Eventlistener: synchrones getObject
-
Hallo,
ich arbeite derzeit an dem Openhab-Adapter und brauche einen synchronen Zugriff auf ioBroker-Object in dem Adapter-Eventlistener.
Gefunden habe ich in der Dokumentation, dass getObject bzw. getForeignObject asynchron per callback arbeitet. Damit komme ich aber nicht weiter.
Wie kann ich das Objekt synchron bekommen, genauer object.common.role?
Gruß,
Sven
-
Hi Darnat,
hast du dein Code im Github? Warum holst du es nicht asynchron und machst das was du willst im Callback? Synchron ist heutzutage voll out. Vielleicht kann man es im Code besser erkennen was du vor hast und genauer helfen.
Grüße,
ldittmar
-
Wäre auch meine Frage. Warum brauchst du es synchron? Schick mal beispielcode. Kriegen wir gelöst
-
Synchrone Ausführung von länger dauernden Funktionen ist in NodeJS nicht vorgesehen. In dieser Welt ist alles auf Callbacks getrimmt, um möglichst viel Parallelität zu ermöglichen.
Es gibt aber eine Möglichkeit, dass dein Code zumindest synchron aussieht. Unter der Haube ist es trotzdem asynchron, aber das wird verschleiert.
Mit TypeScript oder Babel kannst du dafür die async/await-Syntax einer neuen JavaScript-Version verwenden. Das mache ich z.B. hier im Tradfri-Adapter:
https://github.com/AlCalzone/ioBroker.t … cts.ts#L46
async function fixAuthenticationObjects() { const identityObj = await _.adapter.$getObject("info.identity"); // ... }
Das setzt aber voraus, dass die Funktion einen Promise zurückgibt. NodeJS-Callback-Style Funktionen kann man relativ einfach so kapseln, dass sie das tun. In meinem Adapter-Code habe ich das für die wichtigsten Adapter-Funktionen getan:
-
async und await limitiert aber effektiv die Nutzer auf nodejs 8 … das sollte man (leider) immer noch berücksichtigen. nodejs 4 und 6 wären nur mit "normalen" callbacks behandelbar (oder man braucht irgendwelche Kompatibilitätslibs)
-
Hallo,
ich arbeite derzeit an dem Openhab-Adapter und brauche einen synchronen Zugriff auf ioBroker-Object in dem Adapter-Eventlistener.
Gefunden habe ich in der Dokumentation, dass getObject bzw. getForeignObject asynchron per callback arbeitet. Damit komme ich aber nicht weiter.
Wie kann ich das Objekt synchron bekommen, genauer object.common.role?
Gruß,
Sven `
Es gibt tatsächlich die Möglichkeit synchron zu zugreifen, was aber relativ komplex ist. Ich hoffe dass in deinem Fall nur Denkweise geändert werden muss. Kann man Kode irgendwo ansehen? -
Es geht darum, dass im OH Adapter der unten stehende Block den EventListener definiert.
Zur Implementierung des OH-Typen Color benötige ich aus dem Ziel-Objekt in IOB den Typen, da OH z.B. ein PercentType-Wert an ein Color-Objekt schickt.
Also muss ich erkennen können, dass OH ein Prozentwert schickt, dieses aber kein Dimmer als Ziel hat, sondern ein RGB-Wert und entsprechend muss der Wert behandelt werden.
Wie kann ich in Zeile 716 den object.native.type (dort wo bei der Generierung des IOB-Objektes der OH-Typ hinterlegt ist) auslesen?
` > 710 es.addEventListener('message', function (eventPayload) {
711 var event = JSON.parse(eventPayload.data);
712 if (event.type === 'ItemStateEvent') {
713 // smarthome/items/GEG_HZ_Soll/state
714 var parts = event.topic.split('/');
715 var topic = parts[2];
716
717 var value = JSON.parse(event.payload);
718 value.value = oh2iob(value.type, value.value);
719
720 adapter.log.debug('Received [' + adapter.namespace + '.items.' + topic + '] = ' + JSON.stringify(value));
721 adapter.setState(adapter.namespace + '.items.' + topic, value.value, true);
722 }
723 }); `
-
Eine weitere Möglichkeit, die auch in diversen Adaptern verfolgt wird, ist das Vorhalten einer Kopie der relevanten Objekte als Variable (z.B. objects) im Adapter. Diese kann bei Start ("ready"-Event) befüllt werden und im "objectChange" aktualisiert werden.
Damit entfällt der getObject-Aufruf zugunsten eines synchronen Zugriffs auf objects[id].
-
So, ich habe das Problem gelöst. Wie vorgeschlagen werden alle Objekte und Status intern gespeichert.
Nur mit der Aussage, dass ein synchrones Verhalten schneller Vorgänge "out" sei, kann ich mich nicht anschließen.
Das Vorhalten einer Schattenkopie ist eigentlich ein Zeichen für einen Fehler.
Aber der Adapter funktioniert jetzt in meinem Test und das OH Color-Objekt unterstützt jetzt auch OnOff-Kommandos und den Prozenttypen.
Danke nochmal für die Hilfe
Gruß,
Sven
-
Nur mit der Aussage, dass ein synchrones Verhalten schneller Vorgänge "out" sei `
Woher weißt du dass getState/getObject schnell ist? Der Adapter könnte auf einen Multihost-Slave laufen und die Objekte über das Netzwerk und den Master aus einer Datenbank lesen. -
Bei einem Multihost-Szenario wäre eine zentrale Stelle zur Zwischenspeicherung evtl. sinnvoll.
Dort könnte man auch gezielt mit dem Problem von gleichzeitigen Zugriffen umgehen.
Wenn jeder Adapter seine eigene Kopie hat und ich über mehrer Stellen auf den Master zugreifen würde, wer sorgt dann dafür, dass die Daten konsistent bleiben.
Naja, es funktioniert ja auch so. Und ich wollte keine Grundsatzdiskussion vom Zaun brechen
Gruß,
Sven
-
Wenn jeder Adapter seine eigene Kopie hat und ich über mehrer Stellen auf den Master zugreifen würde, wer sorgt dann dafür, dass die Daten konsistent bleiben. `
Üblicherweise haben die Adapter-Instanzen natürlich nur ihre eigenen Objekte im Speicher. Wenn du regelmäßig auf Objekte anderer Adapter zugreifen musst, musst du halt mit callbacks leben (die in der NodeJS-Welt übrigens überall sind) oder auf "pseudo-synchronen" Code per async/await umstellen. -
Hi,
Es ist einfach gewöhnungssache… Das Problem beim Synchron: Ich brauche die Daten von Objekt x um y zu machen, also warte ich bis x da ist und mache solange nichts anderes. Beim Asynchron: Ich brauche die Daten von Objekt x um y zu machen, also rufe ich x auf und mache solange was anderes und wenn irgendwann x fertig ist, macht er y weiter und ich habe solange ganz viele andere Sachen gemacht.
Hier habe ich ein Beispiel, wie ich das benutzt habe. Es funktioniert super und nirgendwo muss das System angehalten werde, um auf irgendwas zu warten, obwohl ich fast nur Daten aus andere Objekten nutze.
https://github.com/ldittmar81/ioBroker. ... fo.js#L745
Grüße,
ldittmar