NEWS
(ERLEDIGT!) TypeScript, viele common/global Scripte --> CPU
-
@oliverio Mittlerweile funktioniert es ohne über NPM zu publizieren und auch mit TypeScript.
Ein externes .ts (liegt in einem Verzeichnis innerhalb iobroker) wird zu .js "kompiliert" (fehlt gerade der Fachbegriff) und im iobroker-TS-Script über require eingebunden.
Was noch nicht funktioniert ist, wenn im externen Script "Dinge" wir sendTo() verwendet werden. Dieses wird dann in iobroker angemeckert, da unbekannt.
Hast Du dazu noch eine Idee?
Gerne im Thread, ganz unten:
https://forum.iobroker.net/topic/70069/einfügen-von-js-klassen-aus-eigenem-npm-modul/47 -
@uwe72 sagte in (ERLEDIGT!) TypeScript, viele common/global Scripte --> CPU:
sendTo
ja das externe script hat ersteinmal keinen bezug zum aktuellen context in dem die funktionen verfügbar sind.
wenn du testweise in einem separaten script von iobroker das folgende ausführst,
dann siehst du alles was im script context verfügbar ist.
wenn du an dein externes script this mit übergibst, dann kannst du dann unter der empfangenden variable dort, alle befehle erreichen.console.log(Object.keys(this).join(",\n"));
Beipsiel
iobroker script
const xx=require("externesSkript"); xx.externeFunktion(this)
externes Skript
export Function externeFunktion(iob) { iob.log("Logausgabe im iobroker log"); }
Hab das jetzt nicht direkt getestet, aber so müsste es grob laufen.
Wenn du im externen script mit vscode arbeitest, dann erwarte da ersteinmal keine syntax überprüfung, da müsste man sciherlich noch eine type definition hinzufügen. aber da weiß ich auch nix
-
@oliverio Danke dir! Werde ich mir anschauen. VG
-
@oliverio
Danke geht:const { Person } = require('/home/iobroker/library/lib.js'); const joe = new Person("Joe", "Müller", 31, this); log(joe.information()); joe.log();
lib.ts
class Person { private nachname: string; private vorname: string; private alter: string; private adapter: any; constructor(vorname, nachname, alter, adapter) { this.vorname = vorname; this.nachname = nachname; this.alter = alter; this.adapter = adapter; } information(): string { return (`Mein Name ist ${this.vorname} ${this.nachname} und ich bin ${this.alter} Jahre alt!!!!1`); } log(): void { this.adapter.log(this.information()); } } module.exports = { Person};
muss nur noch raus bekommen welchen Type
adapter
haben sollte. -
@ticaki sagte in (ERLEDIGT!) TypeScript, viele common/global Scripte --> CPU:
this.adapter.log(this.information());
hm, geht wahrscheinlich nix kauptt, aber ich würde dann lieber this.log nehmen.
this.adapter.log ist die funktion des javascript adapters.
damit umgehst du wahrscheinlich eigene log verarbeitung des javascript-adapters.
ich würde alles was bei this.adapter verfügbar ist in ruhe lassen und nicht verwenden.wäre glaube ich ein hinsweis darauf, das die sandbox des javascript-adapters ein loch hat
lustig ist das adapter in der auflistung, des kleinen testscripts nicht mit aufgeführt wird
-
@oliverio
Lese den Code nochmalthis
ist Personthis.adapter
ist this im javascript adapterHeißt
---lib ------------------ Javascript Adapter this.adapter.log('bla') == this.log('bla')
Hab das extra in adapter umbenannt, weils auch so im adapter gemacht wird (zumindest von mir)
-
ah jetzt, hab nicht in den constructor geschaut.
so sieht es auch aus wenn du einen adapter entwickelst.
da bekommst du über das adapter attribut auch zugriff
aber ist nicht das selbe wie im adapterhier ist übrigens die typeinformation für die befehle im javascript adapter.
https://github.com/ioBroker/ioBroker.javascript/blob/939b0b0a70dd857684afc10be6732467fb3a5208/lib/javascript.d.ts -
@oliverio
Danke da bin ich schon dran, das hier geht, muss nur noch types entfernen, bin aber zu faul Hab eine class SkriptAdapter in der javascript.d.ts in meinem repo hinzugefügt.
https://github.com/ticaki/script-library-example/blob/b51649045526c4c1466da759a05d4edd26b1c871/.iobroker/types/javascript.d.ts#L1728https://github.com/ticaki/script-library-example
class Person { private nachname: string; private vorname: string; private alter: string; private adapter: ScriptAdapter;
-
Habe zwar hier die letzten 2 Kommentare nicht mehr im Detail verstanden, den
grundsätzlichen Ansatz aber schon. Freue mich das Ganze auszuprobieren. Leider erst ab der 2. Wochenhälfte. Auch wenn die Diskussionen auf 2-3 Threads verteilt waren, waren sie dennoch zielführendWerde erst einmal die ursprüngliche Lösung, reines externe TS-File, dieses zu einem *.js "kompilieren" versuchen. Wenn man den Adapter im Konstruktor mit rein gibt, müsste es ja auch ohne Fehlermeldung die *.js Datei erstellen können.
-
@uwe72 sagte in (ERLEDIGT!) TypeScript, viele common/global Scripte --> CPU:
Habe zwar hier die letzten 2 Kommentare nicht mehr im Detail verstanden, den
grundsätzlichen Ansatz aber schon.Dabei geht es um Typen - wenn du mein github repo als basis nimmst werden dort folgende Befehle kompiliert.
// das ist richtig const irgendwas: ScriptAdapter; irgendwas = thisVomJavascriptadapter irgendwas.setState() // folgendes wird ebenfalls kompiliert ist aber falsch und geht nicht setState() // werde das die Tage noch aus der d.ts datei löschen.
Wenn du vscode benutzt um zu programmieren, geht mit dem repo ebenfalls das Autovervollständigen und Tooltips zu Funktionen.
-
@ticaki Ok, ich werde mir deinen Weg auch noch anschauen.
Aber eine sehr simple/schlichte Lösung ist die:
Eine Datei buch.ts in einem externen Verzeichnis, ohne das drum herum
class Buch { private adapter: any; constructor(adapter) { this.adapter = adapter; } public getCurrentWeekdayAsString() : string { var now = new Date(); let weekday = now.getDay(); this.adapter.sendTo("email.0", { from: "uwe.clement@gmail.com", to: "uwe.clement@gmail.com", subject: "Test1", html: "test2" }); return this.getWeekdayAsString(weekday); } public getWeekdayAsString(weekday: number) : string { let weekdayAsString; if (weekday == 1) { weekdayAsString = "Montag"; } else if (weekday == 2) { weekdayAsString = "Dienstag"; } else if (weekday == 3) { weekdayAsString = "Mittwoch"; } else if (weekday == 4) { weekdayAsString = "Donnerstag"; } else if (weekday == 5) { weekdayAsString = "Freitag"; } else if (weekday == 6) { weekdayAsString = "Samstag"; } else if (weekday == 7) { weekdayAsString = "Sonntag"; } else if (weekday == 0) { weekdayAsString = "Sonntag"; } return weekdayAsString; } } module.exports = { Buch};
Buch.ts zu buch.js "kompilieren" (Sorry, Fachbegriff wieder vergessen). Unter Docker muss man im Container drin sein, d.h. z.B. docker exec -it iobroker bash
npx tsc buch.ts
In Iobroker:
const { Buch } = require('/opt/iobroker/my_scripts/buch.js'); const myBook = new Buch(this); log("Heute ist: " + myBook.getCurrentWeekdayAsString());
Funktionierende Log + Emailversand:
Ich freue mich nun auf alle Fälle, dass ich alle global-Scripte eliminieren kann. Halte wie gesagt von dieser Architektur nicht so viel.
-
@uwe72
Das ist keine "simple" Lösung sondern einfach nur aufwendiger wie javascript zu schreiben. Typescript mit any ist javascript nur transpilierbarAber im Ernst, die Lösung ist doch das gleich was ich weiter oben vorgeschlagen habe, der Nachschlag ist nur eine Verbesserung dazu.
Mit Typen wird dir halt
this.adapter.setstate()
als Fehler angezeigt, weil esthis.adapter.setState()
sein müsste.Hat spass gemacht.
-
@ticaki Ich habe nun eben schon alles in TS, deswegen ist es für mich nicht aufwendiger.
Eine Stufe simpler wäre, dass ich nur das buch.js schreibe, nicht transpilieren muss und es dennoch einbinden kann in iobroker.
Dennoch verstehe ich noch nicht den Sinn von dem "drum herum", d.h. die vielen anderen Datei tsconfig,json,.../types/javascript.d.ts?
-
@ticaki ok, das mit den Fehlermeldungen....da wirst Du wohl recht haben. So weit bin ich noch nicht
-
@ticaki Auch wenn wir noch leicht unterschiedliche Lösungen haben, würde ich sagen, dass das gemeinsame Wochenende erfolgreich war.
-
@ticaki und mal im Ernst, das ist schon eine krasse Verbesserung zum bisherigen Konzept, Code über die global.Scripte einzubinden. Man kann nun gezielt Code-Frakmente eibinden an Stellen wo man sie benötigt. Und dies auch noch in TS
-
Hab die Types noch in Ordnung gebracht.
setState()
ist jetzt ein Fehler.Richtig:
const einVariablenName: ScriptAdapter = thisVomJavascriptAdapter; einVariablenName.setState();
-
@uwe72 sagte in (ERLEDIGT!) TypeScript, viele common/global Scripte --> CPU:
Ich habe aus ca. 40 (kleineren) Common-Scripte ca. 25 (größere) gemacht und von 8 global Scripten auf 5 reduziert.
Ich laufe nun zumindest nicht mehr in das CPU-Problem rein. Das Speichern nach dem Ändern eines Global-Script dauert nun ca. 5 Minuten.
Übrigens, das Ändern von Common-Scripten ist nie ein Problem, auch vor der "Optimierung" nicht.
ach.ne...hab ich dir das nicht auf Facebook gesagt... reduziere die Global scripte...
wie war nochmal deine Antwort..ach ja... ICH WEISS -
@arteck ich weiß, dass global-Scripte in common reinkopiert werden. Die Lösung ist es nicht nur global-Scripte zu reduzieren wenn das Ziel ist redundantfreien code zu erzeugen. Wenn du die threads vom Wochenende hier verfolgt, dann gibt es bessere Ansätze. Dein Hinweis brachte mir einfach keinen Mehrwert.
-
Hallo habe heute mal probiert wie bei uwe72 die class Buch von extern aufzurufen habe dafür mittlerweile sogar den gleichen Pfad eingerichtet aber leider ohne Erfolg hab auch zu der Fehlermeldung nichts gefunden. Kann mir dazu jemand weiterhelfen?
const { Buch } = require('/opt/iobroker/my_scripts/buch.js'); const myBook = new Buch(this); log("Heute ist: " + myBook.getCurrentWeekdayAsString());
das ist der Fehler und ich komme nicht darauf woher dieser kommt.