NEWS
Projekt: Javascript Klassen Bibliothek
-
Hallo zusammen,
ständig greife ich auf all die tollen Adapter und Skripte zurück, die einige von euch netter Weise und mit viel Mühe zur Verfügung gestellt haben. Was mir immer fehlte, ist der Teil der Logik unter IoBroker. Dort habe ich immer sehr viel in Javascript umgesetzt und habe mein Konzept einige Male geändert. Mit dem, wie ich es jetzt habe, bin ich eigentlich ganz zufrieden und ich könnte mir vorstellen, ein GitHub Projekt daraus zu machen.
Bevor es los geht, möchte ich aber ein paar Meinungen dazu hören. Vielleicht gibt es sowas ja auch schon...
Also mein Ansatz ist der Folgende:
ich habe im Javascript eine ganze Menge an Klassen erstellt, teilweise mit Vererbung. Diese habe ich immer an die Geräte, ich über verschiedene Adapter in meinem Objektbaum eingebunden habe angepasst. Ein Beispiel:
class Device { constructor(Name,Id) { this._Id = Id; this._Name = Name; this._Debug = Debug; } log(Message) { if (this._Debug) { console.log(this._Name+": " + Message); } } };class boolState extends Device { constructor(Name,Id) { super(Name,Id); } on() { setState(this._Id,true); } off() { setState(this._Id,false); } setSchaltzeit(name,zeit) { setState(PfadSetup+'.'+ this._Name + "." + name,zeit); } getState() { return getBool2(this._Id); } setState(state) { setState(this._Id,state); } wechseln() { setState(this._Id,!getBool2(this._Id)); } set_Callback_Ein_Impuls(callback) { this._callbackEinImpuls = callback; on({id: this._Id,change: "gt"}, obj => { this.log("Ein Impuls"); this._callbackEinImpuls(); }); } set_Callback_Aus_Impuls(callback) { this._callbackAusImpuls = callback; on({id: this._Id,change: "lt"}, obj => { this.log("Aus Impuls"); this._callbackAusImpuls(); }); } set_Callback_Wechsel(callback) { this._callbackWechsel = callback; on({id: this._Id,change: "ne"}, obj => { this.log("Ein Wechsel"); this._callbackWechsel(); }); } set_Callback_Ein(callback) { this._callbackEin = callback; on({id: this._Id}, obj => { this.log("Ein"); if (getBool2(this._Id)) { this._callbackEin(); } }); } set_Callback_Aus(callback) { this._callbackAus = callback; on({id: this._Id}, obj => { this.log("Ein Aus"); if (!getBool2(this._Id)) { this._callbackAus(); } }); } }das ist nur ein kleiner Auszug, der das Prinzip verdeutlichen soll. Ich kann z.B. ein Objekt vom boolState erstellen und dann das Gerät direkt im Javascript wunderbar verwenden.
const _WohnzimmerLampe = new boolState("Lampe Wohnzimmer","FHEM.LampeWohnzimmer.state"); const _WohnzimmerSchalter = new boolState("Schalter Wohnzimmer","FHEM.SchalterWohnzimmer.state"); _WohnzimmerSchalter.set_Callback_Wechsel(function(_WohnzimmerLampe.wechseln()){});Ich kann so sehr schnell einfache Bool States schalten und callbacks einfügen.
Ich habe bereits eine ganze Reihe Klassen erstellt. Z.b. Für eine über Tuya gesteuerte RGB Lampe. Dort übergebe ich beim erstellen keine konkrete ID sondern den Ordner, unter dem alle IDs der Tuya Lampe liegen. Dann kann die Klasse auf diese IDs verschiedene Befehle ausführen. Besonders viel Mühe hat es mich gekostet ein Problem zu beheben, wodurch die Lampe zwischen einzelnen State Änderungen immer, 200ms Zeit braucht. Der Adapter fängt das leider nicht. Möchte ich im Skript also mehrere IDs Ändern, muss dies immer im Abstand von 200ms passieren. Dazu habe ich in der Klasse einen Puffer, der das automatisch steuert. So kann ich mit setRGB(color) dann die Farbe einstellen und 200ms wird der Mode auf Color umgestellt und 200ms wird auf on geschaltet.
Ich habe auch Klassen für Telegramm, Adapter Instanzen (Zum überwachen und Neustarten), Homematic (Dort darf die Zentrale nicht zu viele Geräte gleichzeitig geändert bekommen, weil es sonst zu Überlastungen im Funkverkehr kommt. Dort müssen diese Befehle gepuffert werden), Bewegungsmelder, S7-Adapter, Zeitschaltuhren etc. etc. es würde jetzt den Rahmen spängen.
Besonders gut finde ich, dass ich die Verbindung zum Objekt aus dem Objektbaum vom IoBroker nur an einer Stelle mache. Alle setState, getState, Callbacks etc. werden dann über die Methoden der Klassen immer auf die ID der Instanz ausgeführt. Das macht den code später sehr leserlich und den Austausch von Geräten einfach.
Nicht so gut gefällt mir, das ich noch keine Bessere Möglichkeit gefunden habe, als alle Definitionen, Deklarationen und die Logik in ein einziges Javascript zu packen. Dort bekomme ich jetzt schon immer die Meldung, dass mehr als 100 Callback verwendet werden. Vielleicht gibt es dort noch andere Ideen.
Ich habe heute gelernt, dass ich Objekten sogar später noch Methoden zufügen kann, die dann auf die Variablen der Instanz zugreifen können. Damit könnte ich ein boolState z.B. erweitern um einen Timer, der startet, sobald er auf true wechselt, bei wechsle auf false wieder Stopt und bei Ablauf ein neues Callback ausführt. Damit überwache ich z.B. meine Fenster Kontakte und der Callback wäre dann Telegramm.senden("Schlafzimmerfenster noch geöffnet).
-
Ich habe das hier mal angelegt und erst einmal blanko alles reinkopiert, was ich habe. Das war nie zur Veröffentlichung bestimmt, aber soll als Einstieg gelten
https://github.com/undeat/IoBroker-Javascript-Klassen/blob/main/Vorlage