NEWS
[gelöst] auf globale Objekt kann nicht zugegriffen werden
-
Hallo, ich habe im Ordner "global" ein Script, in welchem ich global gültige Variablen angelegt habe.
Bis jetzt nur direkt eine Variable für jeden Wert in einer "Ebene".Nun wollte ich das Ganze bei neuen Variablen als Objekt aufbauen:
const id = {}; id.automatikfreigaben = {}; id.automatikfreigaben.flur = {}; id.automatikfreigaben.flur.beleuchtung = {}; id.automatikfreigaben.flur.beleuchtung.zustand = '0_userdata.0.Produktiv.Automatikfreigaben.Flur.Beleuchtung.zustand';
Wenn ich dies mache, so kann ich diese Objekte aber nicht innerhalb der Skripte verwenden.
Mit der Autovervollständigung kann ich sie schon mal gar nicht einfügen und kopiere ich den ert rein, so erscheint:Was mache ich falsch?
-
@ben1983 Ich würde mal damit anfangen, das Objekt nicht so umständlich zu definieren:
const id = { automatikfreigaben: { flur: { beleuchtung: { zustand: '0_userdata.0.Produktiv.Automatikfreigaben.Flur.Beleuchtung.zustand' } } } };
EDIT: Ach, Du hast das Objekt in global definiert, und möchtest es (mit Autovervollständigung im Editor?) in anderen Scripts verwenden? Das geht aktuell nicht.
Aber das Script müsste dann trotzdem funktionieren.
Global bedeutet einfach nur, dass der Inhalt der Scripts vor jedes andere Script kopiert wird.
-
@haus-automatisierung Ah ok.
Schade,dass es nicht geht. Dann bekomme ich halt lauter Fehlermeldungen und weiß nicht, ob es wirklich Fehler sind.
Ich habe es so "umständlich" definiert,
da ich einzelne "Bereiche" habe und und dort immer wieder dann etwas hinzufüge.
Also nicht alles in einem Block definiere.Am besten feature request als issue?
-
@ben1983 sagte in auf globale Objekt kann nicht zugegriffen werden:
Am besten feature request als issue?
Zu dem Thema gibt es schon ein paar ähnliche Issues, such mal durch.
-
@haus-automatisierung OK.
Meinst DU es ist "Besser" das Objekt nur dazu definieren, wo es gebraucht wird?
Also dann im worst case 2-3 mal in unterschiedlichen Skripten und den Global Ordner so gar nicht nutzen?Lerne ja gerne dazu
-
@ben1983 Weiß nicht, ob es da den besten Weg gibt. Jeder hat andere Vorzüge. Ich sehe z.B. gern auf einen Blick, was im Script passiert. Und wenn da dann Dinge aus Global kommen, sehe ich das ja nicht mehr. Daher verwende ich den Ordner z.B. gar nicht.
Aber: Geschmackssache.
-
@haus-automatisierung OK.
ist ein gutes Argument.Ich nutze allerdings auch ein Skript für globale Funktionen, die ich oft verwende.
Hab z.B. eine Funktion, die einfach ein senden an die Alexainstanzen wraptfunction sendAlexaMessage(message, deviceId) { setState(deviceId + ".Commands.speak", message); }
Die wird halt sehr oft in unterschiedlichen Skipten verwendet
-
@ben1983 Das mache ich mit
sendTo
/onMessage
-
-
@haus-automatisierung nutzt Du immer sendTo?
Oder auch messageTo (innerhalb von Skripten)? -
@ben1983 sagte in auf globale Objekt kann nicht zugegriffen werden:
Oder auch messageTo (innerhalb von Skripten)?
Ist technisch genau das gleiche.
messageTo
nutzt auchsendTo
. -
@haus-automatisierung OK, danke
Ich bekomme nur bei der messageTo den log geschrieben, was ist denn beim SendTo falsch?
messageTo("Testmessage",{name:"Testname"},(callbackdata)=>{ log(JSON.stringify(callbackdata)); }); sendTo("javascript.0",'toScript', { script: 'script.js.x_testskripte._a_Mesagetest', message: 'Testmessage', data: { flag: true },function(res){ log(JSON.stringify(res)); } }); onMessage("Testmessage",(messagedata,callback) =>{ const myData = {input: messagedata, output:{name:"Test"}}; callback(myData) });
Ps. die funktionieren NUR mit callback,oder?
Also mit return kann man nichts zurückgeben, dass man das Ergebnis einer Funktion in einer Zeile direkt zuweisen kann.
Oder? -
@ben1983 sagte in auf globale Objekt kann nicht zugegriffen werden:
Also mit return kann man nichts zurückgeben, dass man das Ergebnis einer Funktion in einer Zeile direkt zuweisen kann.
Na Du kannst doch mit
sendToAsync
undawait
arbeiten. Ganz normal mit Promises halt.https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#sendtoasync
Oder halt
messageToAsync
:https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#messagetoasync
-
@haus-automatisierung AH ok... hatte mir mal etwas drum rum gebaut, weil damals ein fehler im sendToAsynch war... weiß leider nicht mehr was
async function mySendToAsync(_adapter, cmd, msg) { return new Promise((resolve, reject) => { sendTo(_adapter, cmd, msg, res => { if (!res || res.error) { reject(res ? res.error : new Error('Unknown error')); } else { resolve(res); } }); }); }
also kann man auch normal jetzt das messageToAsynch benutzen, oder wie?
Trotzdem macht er irgendwie meinen Callback nicht, ob wohl ich den aufrufe. (im sendTo)
-
@ben1983 sagte in auf globale Objekt kann nicht zugegriffen werden:
also kann man auch normal jetzt das messageToAsynch benutzen, oder wie?
Hatte ich doch schon geschrieben, dass die beiden Funktionen praktisch identisch sind. Siehe Code.
messageTo
hat halt eine etwas andere Signatur und braucht weniger Infos. Siehe Doku.Ich hatte das hier gefixt: https://github.com/ioBroker/ioBroker.javascript/pull/1343
Einfach die aktuellste Stable version nehmen dann passts.
-
@ben1983 sagte in auf globale Objekt kann nicht zugegriffen werden:
Schade,dass es nicht geht. Dann bekomme ich halt lauter Fehlermeldungen und weiß nicht, ob es wirklich Fehler sind.
du könntest, zumindest temporär, die zeilen in dem das objekt aufgebaut wird in dein skript kopieren. dann funktioniert auch die vervollständigung.
wenn dann alles getestet ist und es funktioniert, dann entfernst du die zeilen wieder und die zeilen aus global wirken.das einmalige definieren in global ist vor allem dann gut, wenn du regelmäßig das objekt in seiner definition erweiterst und du dir arbeit sparen willst. dadurch werden fehler reduziert.
-
@haus-automatisierung OK. Cool.
Könntest DU mir freundlicherweise noch sagen, warum ich hier keinen Log der Daten im Callback bekomme?
Ich finde es nicht. Aufruf wird geloggtsendTo("javascript.0",'toScript', { script: 'script.js.x_testskripte._a_Mesagetest', message: 'Testmessage', data: { flag: true },function(res){ log(JSON.stringify(res)); } }); onMessage("Testmessage",(messagedata,callback) =>{ const myData = {input: messagedata, output:{name:"Test"}}; callback(myData) log("Aufruf "); });
-
@ben1983 sagte in auf globale Objekt kann nicht zugegriffen werden:
Könntest DU mir freundlicherweise noch sagen, warum ich hier keinen Log der Daten im Callback bekomme?
Deine Klammern sind falsch. Die Function ist teil des Msg-Objektes und nicht als separater Parameter definiert. Wenn Du den Code schöner formatieren würdest, siehst Du das auch auf einen Blick
So gehts:
sendTo( 'javascript.0', 'toScript', { script: 'script.js.test.playground', message: 'Testmessage', data: { flag: true } }, (res) => { console.log(JSON.stringify(res)); } ); onMessage('Testmessage', (messagedata, callback) => { console.log('Aufruf'); const myData = { input: messagedata, output: { name: 'Test' } }; callback(myData); });
-
@haus-automatisierung OK. Danke
Beim Verwendet von messageToAsynch tritt dieser Fehler auf:
messageToAsync("Testmessage",{name:"Testname"});
javascript.0 (20591) script.js.x_testskripte._a_Mesagetest: TypeError: Cannot read properties of undefined (reading 'timeout')
-
@ben1983 sagte: "Besser" das Objekt nur dazu definieren, wo es gebraucht wird?
Ja. Die Gruppe "global" verwendet man für häufig verwendete eigene Funktionen.
Mit globalen Objektdefinitionen müllt man sich den RAM der Javascript-Instanz zu, da sie in jedem nicht globalen Skript kompiliert werden.