NEWS
Adapterentwicklung Daten und weiteres
-
Hallo Zusammen,
Habe damit begonnen, meinen ersten Adapter zu entwickeln. Werde ihn dann vorstellen, sobald er "alpha"-Status verlassen hat.
Ich konnte mithilfe der Doku, des Forums und anderen Adaptern schon so einiges machen, ein paar Fragen hätte ich aber trotzdem noch, um das ganze "sauberer" zu implementieren. Ich schreibe jeweils wie ich was verstanden habe, korrigiert mich wenn ich falsch liege.
1. Speicherorte für Daten:
Einstellungsdaten aus der index_m.html werden in "native" gespeichert und können über Adapter.config.x ausgelesen werden. Zwar könnte man diese auch setzen, sollte man aber nicht tun da dies einen Adapterneustart zur Folge hat.
Weitere Daten werden in den normalen "Datenpunkten" abgelegt (setState), die man entweder im Code erstellt (setObject) oder in der io-package unter "instanceObjects" vordefiniert.
Frage: Wo könnte ich Daten ablegen, die wie die "native" nicht sichtbar sind? Konkret geht es um ein API-Token welches ich nicht unbedingt in den States ablegen möchte, der user soll nur die States sehen, die für ihn von Interesse sind.2. CrossOrigin-Problem:
Ich möchte den User in der index_m.html gewisse Einstellungen vornehmen lassen, dann eine API abfragen, und nochmals eine Einstellung vom Benutzer vornehmen. Die API muss ich serverseitig abfragen, da ich vom Browser auch die Cors-Probleme nicht umgehen kann.
Frage: Habe bisher nur die Lösung wie "message" und "sendTo" gesehen (beim sql-Adapter), ist das die Korrekte vorgehensweise, also brauche ich dazu wirklich die "message"-Funktionalität?Vielen Dank schon mal für eure Hilfe im Voraus.
-
Noch ne kleine Zusatzfrage:
Mir passiert immer mal wieder, dass der Adapter irgendwo im Code hängen bleibt (z.B. falscher Zugriff auf nicht existierenden State oder so). Manchmal kommt die entsprechende Meldung im Log, oft kommt aber gar nichts und ich weis nicht wo er hängen geblieben ist.
Wie komme ich an alle Ausgaben, also auch an "RunTimeErrors"?
Aktuell bleibt er mir nach einem await einfach hängen und ich sehe nicht wieso... -
-
Wenn native im Adapter keine option kannst du es ja auchbim Info objekt als native ablegen. Das geht ohne neustart.
-
ja sendto/message ist die richtige vorgehensweise.
-
du müsstest dich per remote in die nodejs instanz des Adapters mit deiner IDE einhängen. Sonst kannst du nur überall logs einbauen.
-
-
@dbweb
Vorher: Richte in VSCode die Debug-Konfiguration "Node.js: Attach to Remote ein", wobei du den Hostnamen/IP des Test-Rechners sowie den dortigen Pfad zum Adapter eintragen musst.Debuggen geht jetzt wie folgt:
-
Stoppe auf dem Test-Rechner deinen Adapter und führe ihn per Kommandozeile folgendermaßen aus:
node --inspect-brk=0.0.0.0:9229 pfad/zur/main.js --force --logs
-
Drücke in VSCode F5
-
-
Dankeschön, habs mit PHPStorm hingekreigt. Debugging inkl. Breakpoints geht wunderbar, sendto/message klappt auch schon, komme gut voran
-
Jetzt muss ich doch nochmals zu 1 nachfragen: Wie kann ich ein 'native' zum Adapter setzen, also einen wert aus Adapter.config.x? Mit setObject erstelle ich ja nur ein Objekt. Mit setState fnde ich irgendwie den Pfad zu dem Objekt nicht, weder via system.adapter.0. noch sonst irgendwie. Hänge da grad etwas...
Neustart danach wäre ganz ok, aber ich müsste erst 2 native setzen, erst danach neu starten, geht das? -
@dbweb
Objekt mitgetObject
lesen, dann bearbeiten und mitsetObject
zurückschreiben -
Tut mir leid, irgendwie habe ich wohl ein Grundkonzept nicht verstanden.
Ein Beispiel:
In der io-package habe ich:"native": { "someVar": "" }
Diese kann ich in der index_m.html an das callback von save(callback) übergeben / setzen:
function save(callback){ var obj = {}; obj['someVar']¨= 'Some Value'; callback(obj); }
und wird damit zur Instanz gespeichert.
in der main.js kann ich dann überAdapter.config.someVar
Darauf zugreifen.
Ich schaffe es aber nicht, diesen Wert zu verändern.
Versucht habe ich z.B. folgendes:Adapter.getObject('config.someVar',function(err, obj){ Adaper.log.info(JSON.stringify(obj); }
liefert NULL.
Habs auch schon über diverses anderes versucht, absolut kein Erfolg.
Zudem:
Wenn ich mit Adapter.getObject('existierendes.irgendwas',function(err,obj){}) etwas hole was es gibt (vorher mit setObject erstellt), dann kriege ich ja trotzdem nicht den Wert dieses Objekes.
Als Beispiel:Adapter.setObjectNotExists('something', { type: 'state', common: {name: 'something', type: 'number', role: '', read: true, write: true}, native: [] },function(){ Adapter.setState('something',42,function(){ Adapter.getObject('something',function(err,obj){ Adapter.log.info(JSON.stringify(obj)); // Gibt aus: {"type":"state","common":{"name":"something","type":"number","role":"","read":true,"write":true},"native":[],"from":"system.adapter.testadapter.0","user":"system.user.admin","ts":1572639560947,"_id":"testadapter.0.something"} }); // kann den state nur damit auslesen Adapter.getState('something',function(err,state){ Adapter.log.info(JSON.stringify(state)); // Gibt aus: {"val":42,"ack":false,"ts":1572639681473,"q":0,"from":"system.adapter.testadapter.0","user":"system.user.admin","lc":1572639558088} }); }); });
Also irgendwas verstehe ich komplett falsch....könnt ihr mir auf die Sprünge helfen?
-
@dbweb Das Objekt das du suchst heißt
system.adapter.<adaptername>.<instanznr>
. Das kannst du dir mitgetObject
holen und bearbeiten. Hier ein Beispiel:
https://github.com/AlCalzone/ioBroker.tradfri/blob/master/src/main.ts#L573Wenn du jetzt eh mit der Entwicklung beginnst, empfehle ich dir: lass die Callbacks sein und nutze die
...Async
-Funktionen mitawait
. Da sparst du dir die ganze Callback-Hölle und dein Code wird lesbarer. -
klar, callbacks waren nur rasch für das Beispiel weil ich vergessen hatte, dass die Methoden async sind. Verwende sonst natürlich async dafür, konnte ja sonst keiner mehr lesen.
-
So, hat alles geklappt. Hatte wohl irgendwie nie die richtige Kombination aus getForeignObject und system.adapter.... ausprobiert, hatte immer nur null oder leere Objekte. Danke für die Hilfe, bin ein ganzes Stück weiter gekommen und werde den Adapter Montag wohl mal vorstellen und auf NPM packen