NEWS
[Problem] Verwendung getObject in Adapter
-
Hallo zusammen,
evtl. bin ich auf dem ganz falschen Weg, aber im Moment stehe ich auf dem Schlauch bei der Weiterentwicklung eines Adapters. Ich brauche dafür den Raum eines Datenpunktes.
Mit JavaScript geht das ganze mittels getObject.
Bei mir zwar aus irgendwelchen Gründen nicht wie z.B. im Skript für die offenen Fenster etc.var raeume = getObject('snips.0.devices.default', 'rooms').enumNames.join(', ')
Bei mir liefert das Skript konträr zur Anleitung ein Array mit den Raumnamen in verschiedenen Sprachen zurück. Daher dieser Code.
var raeume = getObject('snips.0.devices.default', 'rooms').enumNames; var raum = ''; for (let key in raeume) { raum += raeume[key].de; if(key < (raeume.length - 1)) { raum += ", "; } } console.log(raum);
Nicht ganz schön, aber funktioniert. Bei einem Raum wird ein Raum als String ausgegeben, bei mehreren alle Räume durch Kommata getrennt. Soweit so gut.
Mein Problem ist nun das ganz in einen Adapter zu bekommen.
Mein Ansatz
adapter.getObject('devices.default', function (err, obj) { adapter.log.error("Test: " + JSON.stringify(obj)); })
liefert leider keine Räume mit.
{"type":"device","common":{"name":"default"},"from":"system.adapter.snips.0","user":"system.user.admin","ts":1560161784751,"_id":"snips.0.devices.default"}
Ist das in Adaptern grundsätzlich nicht möglich oder habe ich falsche gedacht/die falsche Funktion verwendet?
Danke schon mal für eure Hinweise.
-
probier mal
getForeignObject
-
@htrecksler sagte in [Problem] Verwendung getObject in Adapter:
getForeignObject
Danke für den Vorschlag. War aber nicht das Problem. Es handelt sich um einen Datenpunkt des eigenen Adapters, somit wäre es nicht nötig. Aber hab es getestet:
adapter.getForeignObject('snips.0.devices.default', function (err, obj) { adapter.log.error("Test: " + JSON.stringify(obj)); })
liefert das gleiche Ergebnis.
-
Das Callback-Argument von
getObject
sollte eigentlich eine optionale Eigenschaftenums
enthalten. Bist du sicher, dass das angefragte Objekt zu einer Enum gehört? -
@AlCalzone
Da bin ich leider sicher. Siehe das Skript im Javascript Adapter. Liefert genau die gewünschten Informationen. Wenn auch aus irgendwelchen Gründen anders als in allen Threads hier erklärt. -
@unltdnetworx sagte in [Problem] Verwendung getObject in Adapter:
Siehe das Skript im Javascript Adapter
Der Skripte-Adapter macht noch zusätzliche Magie unter der Haube. Schau dir mal im Admin die Objektdefinition an oder (noch besser) poste sie hier.
-
@AlCalzone
Dann liegt es wohl daran, hatte schon fast sowas vermutet. Die Ausgabe im Adapter passt ja eigentlich zum Admin.Dann muss ich wohl mal den Javascript-Adapter zerlegen.
Zusammengefasst kann man mit getObject außerhalb des Javscript-Adapters keine enums ausgeben lassen?!
-
@unltdnetworx Es gibt Möglichkeiten, an die Enums zu kommen. Ich habe sie nur nicht im Kopf. Stöber mal durch die Syntaxhilfe - ich frag auch mal wen.
-
@AlCalzone sagte in [Problem] Verwendung getObject in Adapter:
@unltdnetworx Es gibt Möglichkeiten, an die Enums zu kommen. Ich habe sie nur nicht im Kopf. Stöber mal durch die Syntaxhilfe - ich frag auch mal wen.
beispiel :
getObject('hm-rpc.0.OEQ0423936.1.STATE', 'functions').enumIds
-
@Dutchman
Vielen Dank, ich probier es heute Abend mal. -
@Dutchman
Jetzt muss ich doch kurz mal nachfragen. Hab es noch nicht gestestet, aber es geht hier um einen Adapter, nicht um ein Skript. Da müsstest es doch mit einem Callback ausgeführt werden, oder sehe ich das falsch? Dann komme ich wieder auf mein getObject vom Anfang und da ist kein enumsID, functions o.ä. enthalten. -
var test = adapter.getObject('devices.default', 'functions').enumIds adapter.log.error("Test: " + JSON.stringify(test));
Ich hatte es schon befürchtet:
by controller[0]: TypeError: Cannot read property 'enumIds' of undefined
@AlCalzone sagte in [Problem] Verwendung getObject in Adapter:
Schau dir mal im Admin die Objektdefinition an oder (noch besser) poste sie hier
{ "from": "system.adapter.snips.0", "user": "system.user.admin", "ts": 1560161784751, "common": { "name": "default" }, "native": {}, "acl": { "object": 1638, "owner": "system.user.admin", "ownerGroup": "system.group.administrator" }, "_id": "snips.0.devices.default", "type": "device" }
Das wäre der Channel, JS wirft das gewünschte aus, der Adapter nicht. Ich werde mir wohl bei Gelegenheit wirklich den Code des JS-Adapters ansehen müssen.
-
@unltdnetworx Wenn ich mir https://github.com/ioBroker/ioBroker.js-controller/blob/master/lib/adapter.js#L3139 so anschaue, musst du manuell die Enums lesen und schauen, ob dein Objekt sich darin befindet. Dazu sollte die Methode
getEnums
(und verwandte) brauchbar sein. -
Zum momentanen Zwischenstand, meine aktuelle Lösung:
adapter.getEnums('rooms', (err, res) => { if (res) { let _result = res['enum.rooms']; for ( let rooms in _result) { if(_result[rooms].common.members == adapter.namespace + '.devices.' + roomid){ //Raum in Enumeration } } } else if (err) { adapter.log.warn('No room set for device in objects enumeration.') } });
Ich stelle den Thread noch nicht auf gelöst, da das auf meinem Windows-Entwicklungssystem funktioniert, auf meinem Linux-Produktivsystem jedoch den Raum als undefined meldet.
-
@unltdnetworx sagte in [Problem] Verwendung getObject in Adapter:
auf meinem Linux-Produktivsystem jedoch den Raum als undefined meldet.
Logge doch zum Debuggen mal
res
auf beiden Systemen als JSON. Dann sollten wir schnell sehen warum. -
Der Vollständigkeit halber noch die Auflösung für mein Problem. Ich hatte dem Raum mehrere Geräte zugeordnet und nur mit die Gesamtheit der Geräte aller Räume mit dem enum-Eintrag des gesuchten Gerätes verglichen. Wenn man alle Geräte in jedem Raum einzeln vergleicht, dann funktioniert es. Im Testsystem war nur ein Gerät zugeorndet und somit funktionsfähig.
adapter.getEnums('rooms', (err, res) => { if (res) { let _result = res['enum.rooms']; for ( let rooms in _result) { for (let thingInRoom in _result[rooms].common.members) { if(_result[rooms].common.members[thingInRoom] == adapter.namespace + '.devices.' + roomid){ //Gerät ist in enum Räume enthalten --> Code einfügen } } } output = output.replace(result.slots[i].rawValue, slotRoom) if(--deviceTasksToGo === 0) { loopDeviceComplete(); } } else if (err) { adapter.log.warn('No room set for device in objects enumeration.') if(--deviceTasksToGo === 0) { loopDeviceComplete(); } } });
Danke an alle für die Vorschäge.
-
Offtopic:
Kann man den Titel nicht mehr ändern? Wollte auf "gelöst" stellen.