NEWS
SOLVED [gelöst] Mein erstes Skript in Java
-
Hallo zusammen,
ich habe vor kurzem mit ioBroker angefangen und bin nun dabei, meine Skripte aus Homematic umzuschreiben. Habe bisher noch keine Berührungspunkte mit Java gehabt und da aller Anfang schwer ist, habe ich mit einer vermeintlich einfachen Zeitschaltuhr für meinen Pool angefangen. Die Pumpe soll um 9 und 15 Uhr für jeweils 3 Stunden laufen.
Das Skript möchte ich mittels Tastendruck in Vis starten und beenden und die Idee ist, dass wenn der Datenpunkt Skriptstart true ist, das Skript startet und bei false deaktiviert wird. Nun möchte ich von euch wissen, ob das Skript soweit okay ist oder ob es auch eleganter gestaltet werden kann und natürlich, ob es funktioniert oder nicht.
Ich muss dazu sagen, dass ich mir gewisse Passagen einfach kopiert und verändert habe, ohne diese wirklich zu verstehen. if (!obj.state.ack && obj.state.val) und {name: 'Skript bei VIS Tastendruck starten'} ist mir im Moment noch unklar^^createState('javascript.0.VIS.Skriptstart', false, {name: 'Skript bei VIS Tastendruck starten'}); on('javascript.0.VIS.Skriptstart', function (obj) { if (!obj.state.ack && obj.state.val) { function Poolpumpe_An() { setState('hm-rpc.0.OEQ0572933.1.STATE'/*Steckdose Poolpumpe Garage STATE*/, true); } function Poolpumpe_Aus() { setState('hm-rpc.0.OEQ0572933.1.STATE'/*Steckdose Poolpumpe Garage STATE*/, false); } schedule({hour: 09, minute: 0}, function () { Poolpumpe_An(); } ); schedule({hour: 15, minute: 0}, function () { Poolpumpe_An(); } ); schedule({hour: 12, minute: 0}, function () { Poolpumpe_Aus(); } ); schedule({hour: 18, minute: 0}, function () { Poolpumpe_Aus(); } ); } });
-
@Dominik-F sagte in Mein erstes Skript in Java:
Hallo zusammen,
ich habe vor kurzem mit ioBroker angefangen und bin nun dabei, meine Skripte aus Homematic umzuschreiben. Habe bisher noch keine Berührungspunkte mit Java gehabt und da aller Anfang schwer ist, habe ich mit einer vermeintlich einfachen Zeitschaltuhr für meinen Pool angefangen. Die Pumpe soll um 9 und 15 Uhr für jeweils 3 Stunden laufen.
Das Skript möchte ich mittels Tastendruck in Vis starten und beenden und die Idee ist, dass wenn der Datenpunkt Skriptstart true ist, das Skript startet und bei false deaktiviert wird. Nun möchte ich von euch wissen, ob das Skript soweit okay ist oder ob es auch eleganter gestaltet werden kann und natürlich, ob es funktioniert oder nicht.
Ich muss dazu sagen, dass ich mir gewisse Passagen einfach kopiert und verändert habe, ohne diese wirklich zu verstehen. if (!obj.state.ack && obj.state.val) und {name: 'Skript bei VIS Tastendruck starten'} ist mir im Moment noch unklar^^createState('javascript.0.VIS.Skriptstart', false, {name: 'Skript bei VIS Tastendruck starten'}); on('javascript.0.VIS.Skriptstart', function (obj) { if (!obj.state.ack && obj.state.val) { function Poolpumpe_An() { setState('hm-rpc.0.OEQ0572933.1.STATE'/*Steckdose Poolpumpe Garage STATE*/, true); } function Poolpumpe_Aus() { setState('hm-rpc.0.OEQ0572933.1.STATE'/*Steckdose Poolpumpe Garage STATE*/, false); } schedule({hour: 09, minute: 0}, function () { Poolpumpe_An(); } ); schedule({hour: 15, minute: 0}, function () { Poolpumpe_An(); } ); schedule({hour: 12, minute: 0}, function () { Poolpumpe_Aus(); } ); schedule({hour: 18, minute: 0}, function () { Poolpumpe_Aus(); } ); } });
Ich denke für das was du tun willst ist das so nicht ideal. Aber erst einmal zur Funktion:
- als erstes wird ein Datenpunkt angelegt. Mit diesem Datenpunkt soll später das eigentliche Script gestartet werden.
- als zweites wird ein Trigger auf diesen neuen Datenpunkt definiert. Die Triggerfunktion bekommt das Objekt des Datenpunktes als Parameter mitgegeben (obj), und die Trigger-Funktion aktiviert bei jeder Aktualisierung des Datenpunktes.
- In der Funktion wird mit dem If zunächst abgeprüft ob der Datenpunkt "wahr" ist und "bestätigt" wurde oder nicht (!obj.state.ack). Dazu muss man wissen das das sogenannte 'acknowledge' oder 'ack' dazu dient festzustellen ob eine Änderung an einem Datenpunkt auch von der Hardware bestätigt wurde. Wenn du zum Beispiel eine Pumpe einschalten willst, dann setzt du den Datenpunkt für die Pumpe, wobei das ack nicht mit gesetzt wird. Wenn der Adapter dann die Pumpe erfolgreich eingeschaltet hat setzt er den Datenpunkt nochmal, aber dieses Mal mit ack.
- Die schedules werden dann in der Trigger-funktion gesetzt. Das sollte soweit klar sein hoffe ich.
Nun dazu warum das nicht ideal ist:
- Die Schedules werden gesetzt wenn der Datenpunkt auf Wahr gesetzt wird, aber nie gelöscht.
- Das 'ack' des steuernden Datenpunktes wird nie gesetzt, sprich die Shedules werden ggf. mehrfach gesetzt.
Nun zur aus meiner Sicht korrekten Umsetzung:
//createState('javascript.0.VIS.ZeitschaltungPumpeAktiv', false, {name: 'Zeitschaltung Poolpumpe'}); let PumpeAktiv = false; on({id: 'javascript.0.VIS.ZeitschaltungPumpeAktiv', change: 'ne'} , function (obj) { PumpeAktiv = obj.state.val; } function Poolpumpe_An() { setState('hm-rpc.0.OEQ0572933.1.STATE'/*Steckdose Poolpumpe Garage STATE*/, PumpeAktiv); } function Poolpumpe_Aus() { setState('hm-rpc.0.OEQ0572933.1.STATE'/*Steckdose Poolpumpe Garage STATE*/, false); } schedule({hour: 09, minute: 0}, Poolpumpe_An ); schedule({hour: 15, minute: 0}, Poolpumpe_An ); schedule({hour: 12, minute: 0}, Poolpumpe_Aus ); schedule({hour: 18, minute: 0}, Poolpumpe_Aus );
Das entscheidende bei dieser Methode ist, das die Pumpe nur dann EIN geschaltet wird, wenn der Datenpunkt ZeitschaltungPumpeAktiv auf true gesetzt ist. Dazu wird bei jeder Änderung des Datenpunktes (change: 'ne') die interne Skriptvariable PumpeAktiv gesetzt wird. Diese Variable wird dann dazu benutzt die Pumpe einzuschalten. Hier habe ich einen Trick genutzt. Der Schaltbefehl wird Immer gesetzt, allerdings wird die Pumpe nur EIN geschaltet wenn die Variable auf true steht. Die Schedules zum abschalten sind immer aktiv, so das die Pumpe nicht alleine durch deaktiveren der Zeitschaltung auf Dauerlauf geschaltet werden können.
Das createState am Anfang habe ich absichtlich deaktiviert. Ich lege die notwendigen Datenpunkte immer manuell an, so das die Skripte keine Funktionen zum anlegen selber besitzen. Das ist aber Geschmacksache.A.
p.s. Das was du da genutzt hast ist Javascript. Java ist noch etwas ganz anderes
-
Zuerst vielen Dank für deine ausführliche Antwort, du hast sehr gute Erklärungen geschrieben. Die Erklärung hat mir wirklich weitergeholfen und einige Unklarheiten bereinigt,
Ich würde dir gerne noch die ein oder andere Frage dazu stellen. Ich hatte im ersten Versuch das Phänomen, dass ich 2 mal den Taster betätigen musste, um das Skript zu deaktivieren. Wenn ich deine Erklärung jetzt richtig verstanden habe, habe ich den "Fehler" durch den 'acknowledge' verursacht weil ich mit dem zweiten Tasterdruck den ack gesetzt habe?
Die zweite Frage ist, warum du mit den Skripten keine Datenpunkte anlegst? Gibt es da einen bestimmten Grund für, also warum man das nicht tun sollte?
-
@Dominik-F
Die erste Frage kann ich dir nicht beantworten. Der Skript Teil den du gepostet hast enthält keine Funktion wie man die Zeitschaltung deaktivieren kann.Bei der zweiten Frage ist es einfacher. Ich mache es aus Gründen des entwicklungsflusses nicht. Während der Entwicklung eines Skriptes lege ich zuerst immer nur eines lokale variable an, mit der ich die gesamte Funktionalität teste. Wenn dann alles fertig ist verbinde ich diese Variable mit einem Datenpunkt.
Ich gehe nicht davon aus das es zu Problemen führt wenn das anlegen des Datenpunkte im Skript bleibt. Einziger vorstellbarer Effekt kann sein das der initiale wert des Datenpunktes bei dem Befehl gesetzt wird, sprich jedes Mal wenn das Skript gestartet wird wird der datenpunkt auf falsch gesetzt. Ob das so ist weiß ich aber nicht sicher.A.
-
@Asgothian sagte:
kann sein das der initiale wert des Datenpunktes bei dem Befehl gesetzt wird, sprich jedes Mal wenn das Skript gestartet wird wird der datenpunkt auf falsch gesetzt.
Nein, existierende Datenpunkte werden nicht überschrieben.
-
Alles klar. Vielen Dank für die ausführliche und verständliche Antwort. Bin sehr begeistert von dem Forum hier