NEWS
Info: Auslagerung von Global-Scripten ins Filesystem
-
Summary:
Beispiel wie man ein Global-Script ins Filesystem auslagert und dann in den Common-Scripten darauf zugreift. Eben nur in den Scripten wo man die Inhalte aus Global auch wirklich benötigt. Ein Beispiel für JavaScript und ein Beispiel für TypeScript.Zielsetzung:
Da ich wieder an die Grenzen gekommen bin was RAM/CPU angeht, habe ich das Thema nochmals aufgegriffen, die Global-Scripte in externe Module auszulagern. Ich möchte in diesem Post eine (für mich) funktionierende Lösung vorstellen. Ich war früher Java Entwickler, dies ist allerdings bereits 15 Jahre her. JavaScript/TypeScript habe ich nie gelernt, also habe ich nicht den Anspruch professionellen Code zu schreiben. Es existieren viele Posts dazu, wollte aber (auch für mich) zusammenschreiben wie es funktionieren kann, insbesondere wenn ich in 2 Jahren nochmals wissen möchte wie es gingHintergrund:
Das Konzept mit den global/common Scripte ist ja leicht fragwürdig, da der Inhalt jedes global-Script in jedes common-Script an den Anfang kopiert wird, obwohl der Inhalt eines global-Scriptes nicht in jedem common-Script benötigt wird. Es wird auch im Forum an diversen Stellen abgeraten überhaupt global-Scripte zu verwenden (vermutlich wegen RAM,CPU, Performance,...). Aber warum verwende ich überhaupt global-Scripte? Da ich eben "ein Stück Softwarecode" nur einmal schreiben möchte und es an vielen Stellen verwenden möchte. Das geht eben nicht ohne die Verwendung von global-Scripte. Ich mag keinerlei Duplizierung von Code.D.h. ich kann es nicht über global-Script machen, da dieser Code in jedes Script reinkopiert wird, d.h. wenn ich in 3 von 100 common-Scripten was aus global brauche, dann ist es in 97 Scripten unnötigerweise drin. Wenn dies hunderte Zeilen von Code sind ist dies einfach unnötig. Insbesondere wenn es bei TS noch "kompiliert" werden muss.
Weiterer Schwachpunkt: Wenn wenigstens die global-Scripte nur in die common-Scripte reinkopiert werden würden aus der gleichen JavaScript-Instanz wäre auch schon was geholfen. Aber dies geht auch nicht. Die Instanz wird beim Kopieren nicht berücksichtigt
Anforderung:
Mir geht es also einfach darum, dass ich keinen Code doppelt schreiben möchte. In jedem common-Script möchte ich (ausgelagerte) Code-Stellen referenzieren.Lösungsbeispiel per JavaScript
Externe Datei:
/opt/iobroker/my_scripts/haus.jsfunction getNumberRooms() : number { return 347; } module.exports = { getNumberRooms };
ioBroker common-Script:
const { getNumberRooms } = require('/opt/iobroker/my_scripts/haus.js'); log("Anzahl der Räume sind: " + getNumberRooms());
Logausgabe:
javascript.2 20:43:23.456 info script.js.common._ModuleTest.Haus: Anzahl der Räume sind: 347
Lösungsbeispiel per TypeScript
Externe Datei:
/opt/iobroker/my_scripts/kalender.tsclass Kalender { private adapter: any; private myState: string; constructor(adapter, myState) { this.adapter = adapter; this.myState = myState; } public getCurrentWeekdayAsInteger() : number { var now = new Date(); return now.getDay(); } public updateState() { this.adapter.log("Update state within external file"); this.adapter.setState(this.myState, this.getCurrentWeekdayAsInteger()); } public sendTelegram() { this.adapter.log("Send telegram within external file"); this.adapter.sendTo("telegram.0", "Weekday is: " + this.getCurrentWeekdayAsInteger()); } } module.exports = { Kalender};
Transpilieren von TypeScript nach JavaScript
kalender.ts muss zu kalender.js transpiliert werden. Unter Docker muss man im Container drin sein, d.h. z.B. docker exec -it iobroker bashnpx tsc kalender.ts
--> Es entsteht die Datei kalender.js im gleichen Verzeichnis.
ioBroker common-Script:
const { Kalender } = require('/opt/iobroker/my_scripts/kalender.js'); var myStateState = "0_userdata.0.html.test_module"; createState(myStateState, -1, { name: myStateState, desc: myStateState, type: 'number', read: true, write: true }); setState(myStateState, -1); const myCalender = new Kalender(this, myStateState); log("Heute ist: " + myCalender.getCurrentWeekdayAsInteger()); myCalender.sendTelegram(); log("Wochentag is: " + getState(myStateState).val); myCalender.updateState(); log("Wochentag is: " + getState(myStateState).val);
Logausgabe:
javascript.2 20:53:14.743 info script.js.common._ModuleTest.Intern: Heute ist: 5 javascript.2 20:53:14.743 info script.js.common._ModuleTest.Intern: Send telegram within external file javascript.2 20:53:14.746 info script.js.common._ModuleTest.Intern: Wochentag is: -1 javascript.2 20:53:14.746 info script.js.common._ModuleTest.Intern: Update state within external file javascript.2 20:53:14.747 info script.js.common._ModuleTest.Intern: Wochentag is: 5
Zudem wird die Telegram Nachricht versendet: