NEWS
[gelöst] Mein erstes Script - Temperaturdifferenz bewerten
-
Hallo,
ich bin gerade dabei mein erstes, sehr einfaches Script zu schreiben um mich ein wenig in Javascript einzuarbeiten.
Vielleicht gibt es ja jemanden, der mich ein wenig anleiten kann.
Hier also meine Aufgabe:
Ich möchte ein Script schreiben, dass die Temperaturdifferenz zwischen IST und SOLL errechnet und bewertet. Dabei sollte das Ergebnis (in der Form [0] für Abweichung <= 1 Grad, [1] für Abweichung > 1 Grad negativ, [2] für Abweichung > 1 Grad positiv) in ein Objekt geschrieben werden um es dann später in vis für die Formatierung der Anzeige nutzen zu können.
Mein erster kläglicher Ansatz, der zumindest das Objekt anlegt is dieser:
// Script zum Setzen von States für die Visualisierung von Temperaturdifferenzen var tempdiffAZ = "hm-rpc.0.JEQXXXXXXX.2.SETPOINT" - "hm-rpc.0.JEQXXXXXXX.1.TEMPERATURE"; createState ('vis.tempstatus.AZ'); if(tempdiffAZ >= 1) { setState('javascript.0.vis.tempstatus.AZ', 1); } else { setState('javascript.0.vis.tempstatus.AZ', 0); }
Allerdings habe ich es irgendwie nicht geschafft, dass er den State entsprechend meiner Vorstellung schreibt (Ausführung manuell).
Außerdem habe ich im Moment keinen Ansatz wie ich die Differenz in einem verschachtelten "if" und dann auch noch nach positiv und negativ bewerten kann.
Und die letzte Hürde ist die automatische Ausführung des Scripts bei Änderung. Das müsste doch eigentlich mit der "on" Funktion gehen, aber wie? Und wo (im Script)?
Kann mich vielleicht jemand ein bisschen in die richtige Richtung schubsen? Außerdem habe ich offensichtlich noch ein bisschen Probleme mit der Syntax. Gibt es da vielleicht einen Link den Ihr empfehlen könnt?
Danke.
MfG, André
-
Hallo Andre,
hier mein Vorschlag mit Kommentaren:
// Script zum Setzen von States für die Visualisierung von Temperaturdifferenzen // State vom Type Number (0) erstellen für VIS Weiterverwendung createState('vis.tempstatus.AZ', 0, {name: 'Hier lesbaren Namen eintragen'}); // Immer wenn Temp sich ändert, die Differenz neu berechnen. on('hm-rpc.0.JEQXXXXXXX.1.TEMPERATURE', function (data) { var differenz = getState('hm-rpc.0.JEQXXXXXXX.2.SETPOINT').val - data.newState.val; // Variable differenz nur innerhalb der Subscription if (differenz >=1) { setState('javascript.0.vis.tempstatus.AZ', 1); } else setState('javascript.0.vis.tempstatus.AZ', 0); }); // Immer wenn Setpoint geändert wird, auch die Differenz neu berechnen. Diesmal mit Kurzschreibweise on('hm-rpc.0.JEQXXXXXXX.2.SETPOINT', function (data) { var differenz_status = (data.newState.val - getState('hm-rpc.0.JEQXXXXXXX.1.TEMPERATURE').val >= 1) ? 1 : 0; // wenn Differenz aus aktuellem Setpoint und temp >= 1 dann wird differenz 1, sonst 0; setState('javascript.0.vis.tempstatus.AZ', differenz_status); }); ````Du solltest später die langen Datenpunktnamen für die Übersichtlichkeit durch kurze idVariablen ersetzen.
var idSetpoint = 'hm-rpc.0.JEQXXXXXXX.2.SETPOINT',
idTemperatur = 'hm-rpc.0.JEQXXXXXXX.1.TEMPERATURE',
idDifferenz_Status = 'javascript.0.vis.tempstatus.AZ'Gruß Pix
-
Vorschlag mit Ausführung bei Scriptstart, Istwertänderung oder Sollwertänderung:
// Datenpunkt-ID var iddiff = "javascript.0.vis.tempstatus.AZ"; var idist = "hm-rpc.0.JEQXXXXXXX.1.TEMPERATURE"; var idsoll = "hm-rpc.0.JEQXXXXXXX.2.SETPOINT"; // Variablendeklaration und Initialisierung bei Scriptstart var ist = getState(idist).val; var soll = getState(idsoll).val; // Auswertung der Temperaturdifferenz function tempdiff() { var status = 0; if (ist - soll < -1) status = 1; if (ist - soll > 1) status = 2; setState(iddiff, status); } tempdiff(); // Scriptstart on(idist, function(dp) { ist = dp.newState.val; tempdiff(); }); on(idsoll, function(dp) { soll = dp.newState.val; tempdiff(); });
-
Klasse, vielen Dank!
@pix: Danke für die ausführlichen Kommentare und den Tipp mit den kurzen ID-Variablen. Das macht die Sache wirklich deutlich übersichtlicher!
@paul53: Ich habe mir mal deinen Vorschlag gegriffen und umgesetzt. Läuft super und ist sehr schön logisch nachvollziehbar!
Bei mit sieht das Ganze dann jetzt so aus:
!
// Script zum Setzen von States für die Visualisierung von Temperaturdifferenzen ! // Datenpunkt anlegen createState('vis.tempstatus.AZ', 0, {name: 'TempStatus AZ'}); ! // Datenpunkt-IDs var idAZdiff = "javascript.0.vis.tempstatus.AZ"; var idAZist = "hm-rpc.0.JEQXXXXXXX.1.TEMPERATURE"; var idAZsoll = "hm-rpc.0.JEQXXXXXXX.2.SETPOINT"; ! // Variablendeklaration und Initialisierung bei Scriptstart var AZist = getState(idAZist).val; var AZsoll = getState(idAZsoll).val; ! // Auswertung der Temperaturdifferenz function tempdiffAZ() { var status = 0; if (AZist - AZsoll < -1) status = 1; if (AZist - AZsoll > 1) status = 2; setState(idAZdiff, status); } ! // Aufruf der Funktion bei Scriptstart tempdiffAZ(); ! // Aufruf der Funktion bei Änderung TEMPERATURE on(idAZist, function(dp) { AZist = dp.newState.val; tempdiffAZ(); }); ! // Aufruf der Funktion bei Änderung SETPOINT on(idAZsoll, function(dp) { AZsoll = dp.newState.val; tempdiffAZ(); }); !
Allerdings habe ich noch das createState von pix eingefügt. Ist das sinnvoll?Nunja, das Script läuft nun so vor sich hin und tut das, was es soll.
Jetzt möchte ich das Script aber nicht nur für den einen Raum eine solche Bewertung machen lassen, sondern auch für andere Räume. Mein Ansatz wäre jetzt, das Scrpt analog zu erweitern. Etwa so:
!
// Script zum Setzen von States für die Visualisierung von Temperaturdifferenzen ! // Datenpunkt anlegen createState('vis.tempstatus.AZ', 0, {name: 'TempStatus AZ'}); createState('vis.tempstatus.WZ', 0, {name: 'TempStatus WZ'}); ! // Datenpunkt-IDs var idAZdiff = "javascript.0.vis.tempstatus.AZ"; var idAZist = "hm-rpc.0.JEQXXXXXXX.1.TEMPERATURE"; var idAZsoll = "hm-rpc.0.JEQXXXXXXX.2.SETPOINT"; var idWZdiff = "javascript.0.vis.tempstatus.WZ"; var idWZist = "hm-rpc.0.JEQXXXXXXX.1.TEMPERATURE"; var idWZsoll = "hm-rpc.0.JEQXXXXXXX.2.SETPOINT"; ! // Variablendeklaration und Initialisierung bei Scriptstart var AZist = getState(idAZist).val; var AZsoll = getState(idAZsoll).val; var WZist = getState(idWZist).val; var WZsoll = getState(idWZsoll).val; ! // Auswertung der Temperaturdifferenz function tempdiffAZ() { var status = 0; if (AZist - AZsoll < -1) status = 1; if (AZist - AZsoll > 1) status = 2; setState(idAZdiff, status); } function tempdiffWZ() { var status = 0; if (WZist - WZsoll < -1) status = 1; if (WZist - WZsoll > 1) status = 2; setState(idWZdiff, status); } ! // Aufruf der Funktion bei Scriptstart tempdiffAZ(); tempdiffWZ(); ! // Aufruf der Funktion bei Änderung TEMPERATURE on(idAZist, function(dp) { AZist = dp.newState.val; tempdiffAZ(); }); on(idWZist, function(dp) { WZist = dp.newState.val; tempdiffWZ(); }); ! // Aufruf der Funktion bei Änderung SETPOINT on(idAZsoll, function(dp) { AZsoll = dp.newState.val; tempdiffAZ(); }); on(idWZsoll, function(dp) { WZsoll = dp.newState.val; tempdiffWZ(); }); !
Ist das der richtige Ansatz oder bekomme ich da vielleicht irgendwann Probleme?Macht es unter Umständen Sinn für jeden Raum ein separates Script zu nutzen?
Danke.
MfG, André
-
Allerdings habe ich noch das createState von pix eingefügt. Ist das sinnvoll? `
Ich bevorzuge die Erzeugung von Datenpunkten im Reiter "Objekte", da man dabei gleich sinnvolle common-Attribute eingeben kann.
@andre:Macht es unter Umständen Sinn für jeden Raum ein separates Script zu nutzen? `
Ja, das macht Sinn, da man dann Copy & Paste besser anwenden kann. Eine gemeinsame Funktion gibt es ohnehin nicht.Bei sinnvoller Vergabe der Datenpunktnamen kann man die Anpassung nach Copy & Paste auf eine Zeile beschränken (var raum = "AZ";), wie das Beispiel des http://forum.iobroker.org/viewtopic.php?f=21&t=1337 zeigt.
-
Ok, und wie verhält es sich mit den Ressourcen von ioBroker bzw. vom Javascript Adapter? Was ist denn Resourcen schonender, ein großes Script oder viele Kleine?
MfG, André
Gesendet mit Tapatalk.
-
wie verhält es sich mit den Ressourcen von ioBroker bzw. vom Javascript Adapter? Was ist denn Resourcen schonender, ein großes Script oder viele Kleine? `
Das macht wohl bei diesem Script keinen nennenswerten Unterschied. -
Hallo André,
Wichtiger ist, dass du den Überblick behältst. Ich habe derzeit über 100 Skripte, viele mit mehreren Hundert Zeilen. Mit organisierter Namensvergabe und möglichst einheitlicher Struktur innerhalb der Skripte geht das ganz gut. Immer schön kommentieren, das hilft.
Gruß
Pix
Gesendet mit Tapatalk
9054_events.jpg