NEWS
Skript zur Heizungs-, Licht-, … steuerung
-
Moin,
ich habe ein kleines Skript geschrieben um bei mir im Haus die Heizung und die Lichter zu steuern. Es können bestimmte Aktionen bei Statusänderungen und zu bestimmten Uhrzeiten ausgeführt werden. Beispiel, die Heizung soll Nachts von 23:00 bis 06:00 auf 10 Grad und tagsüber von 06:00 bis 23:00 auf 20 Grad gestellt werden, aber nur dann wenn das Fenster zu ist. Ist das Fenster auf, wird die Heizung ausgestellt.
Das dazugehörige Regelwerk ist leider im Skript abzulegen. Falls jemand eine bessere und einfachere Lösung kennt, bitte Mail an mich!
Vielleicht hat jemand Interesse an dem Skript bzw. noch ein paar Ideen?
! ```
`// *******************************************************************************
// Beschreibung: Mit dem Skript kann man zu bestimmten Zeiten und Ereignissen
// (Staus von Objekten) anhand eines Regelswerks Aktionen (setzen eines Status
// in einem Objekt) ausführen.
//
// Version: 0.1 - Erstellung Skript (27.04.2018)
// *******************************************************************************
! // **************************************************************************
// Dokumentation (Anfang)
// **************************************************************************
! /*
! Mit dem folgendem Skript kann man zu bestimmten Zeiten und Ereignissen (Staus von Objekten)
anhand eines Regelswerks Aktionen (setzen eines Status in einem Objekt) ausführen.
Die Reglen werden alle x Sekunden und bei jeder Statusänderung der Objekte
die in state stehen durchlaufen. Eine Regel wird nur bei einer Statusänderung
ausgeführt zum vorherigen Lauf ausgeführt.
D.h. ändert sich der Status nicht, wird auch die Regel nicht nochmals angewandt.
! Die Regeln werden in dem Array task als Elemente hinterlegt. Jedes Element ist ein Objekt
welches folgende Eigenschaften (properties) enthält: rulename, active, time, state und rule.
Wobei die properties time, state und rule jeweils Arrays von Objekten als Werte enthalten.
! Aufbau Regelsatz:
=================
! task[ri++] = {
! // Beschreibung bzw. Name der Regel
rulename: "Wohnzimmerlicht",.
! // Regel ist aktiv (true) oder inaktiv (false)
active: true,
! // Bestimmung wann eine Regel zeitlich aktiv ist (das Element time kann auch fehlen)
time: [ { name: "Bezeichner1", from: "hh:mm", to "hh:mm", weekday: "Sa,So, ..." },
{ name: "Bezeichner2", from: "hh:mm", to "hh:mm", weekday: "Sa,So, ..." },
... ],
!
// Status eines Objektes (das Element state kann auch fehlen)
state: [ { name: "Bezeichner3", id: ObjektID, value: wert },
{ name: "Bezeichner4", id: ObjektID, value: Wert },
{ name: "Bezeichner5", id: objektID },
.... ],
! // Regelwerk
rule: [ { name: "r1", query: "((a && h) && t1 && x)", id: idHeizung, value: 20.0 },
.... ]};
! Element time
============
Um in einer Regel Zeiten zu berecksichtigen ist das Element time zu füllen.
Time ist ein Array von Objekten mit den Elementen name, from, to und weekday.
! task[ri++] = {rulename: "Heizung Wohnzimmer", active: true,
!
// t1 ist gültig (true) am Samstag und Sonntag zwischen 06:00 und 09:00, sonst ist t1 false.
// t2 ist gültig (true) am Samstag und Sonntag zwischen 15:30 und 22:00, sonst ist t2 false.
// from und to können Zeiten von 00:00 bis 24:00 enthalten. Bei Weekday kann Mo,Di,Mi,Do,Fr,Sa,So oder nichts stehen.
// Nichts ist gleichzusetzen mit allen Tagen
! time: [ { name: "t1", from: "06:00", to: "09:00", weekday: "Sa,So" },
{ name: "t2", from: "15:30", to: "22:00", weekday: "Sa,So" } ],
! ....
};
! Element state
=============
Um in einer Regel den Status von Objekten zu berücksichtigen gibt es 2 Optionen, die auch
kombiniert werden können.
! Option 1
! task[ri++] = {
rulename: "Heizung Wohnzimmer", active: true, time: [ ... ],
! // a ist immer dann wahr (true) wenn der Wert des Objektes in dem Element id: den Wert des Elements value: enthält. In dem Bsp.
// ist Status "a" wahr, wenn das Objekt javascript.0.anwesend den Wert true enthält. Sonst ist der Status "a" falsch.
// h ist immer wahr (true) wenn das Objekt javascript.0.heizungssteuerung den Wert 0 enthält, sonst false.
// Unter Value: können auch Objekte oder Funktionen stehen.
// x ist wahr, wenn der Wert in javascript.0.varx gleich { a.x = 1, a.y = 2 } entspricht
// y ist wahr, wenn der wert in javascript.0.vary gleich 4 ist.
! state: [ { name: "a", id: "javascript.0.anwesend", value: true },
{ name: "h", id: "javascript.0.heizungssteuerung", value: 0 },
{ name: "x", id: "javascript.0.varx", value: { a.x = 1, a.y = 2 },
{ name: "y", id: "javascript.0.vary", value: function() { return 1+3; } } ],
! rule: [ ... ]
! };
! Option 2
! task[ri++] = {
rulename: "Heizung Wohnzimmer", active: true, time: [ ... ],
! // Im Gegensatz zur Option 1, fehlt das Element value:. . Es findet nicht wie in Option 1 eine Prüfung des
// Objetes im Element id: mit dem Element value: auf Gleichheit statt, sondern der Wert (Status) des Objektes
// im Element id: wird in einem Element Bezeichner.value und Bezeichner.oldVlaue hinterglegt.
// Bei Start des Skritpes sind die Werte von Bezeichner.value und Bezeichner.oldValue gleich.
// Bsp. der Wert des Objektes javascript.0.anwesend ist gleich "ja", dann enthlält b.value den Wert "ja" und a.oldValue
// auch den Wert "ja". Ist der Wert von Status beim nächsten Durchlauf "nein". Dann ist b.value gleich "nein" und
// b.oldValue gleich "ja"
! state: [ { name: "b", id: "javascript.0.anwesend" } ],
! rule: [ ... ]
! };
! Element rule
============
In dem Element rule sind die einezelnen Regeln (query) für einen task hinterlegt. Die Regeln
(query Einträge) werden sequentiell abgearbeitet. Ist eine Relgel "wahr", dann wird keine
weitere Regel in dem Task durchlaufen. Ist keine Regel in den Query Einträgen
gültig, dann wird auch nichts weiter gemacht!
Wenn eine Regel (query Eintrag) wahr ist, dann wird der Status in dem Element id: auf den Wert
des Elements value: gesetzt. Der Wert in value: kann ein wert, objekt oder eine funktion sein.
Zusätzlich kann man noch mit dem Element func: eine Funktion hinterlegen die ausgeführt wird.
Als Übergabeparameter dient der wert im Element value:
! task[ri++] = {rulename: "Heizung Wohnzimmer", active: true, time: [ { name: "t1", from: "06:00", to: "09:00", weekday: "Sa,So" }, { name: "t2", from: "15:30", to: "22:00", weekday: "Sa,So" } ],
! state: [ { name: "a", id: "javascript.0.anwesend" , value: true },
{ name: "b", id: "javascript.0.anwesend" }
{ name: "h", id: "javascript.0.heizungssteuerung", value: 0 },
{ name: "x", id: "javascript.0.varx", value: { a.x = 1, a.y = 2 },
{ name: "y", id: "javascript.0.vary", value: function() { return 1+3; } } ],
! // regel r1 ist tritt ein, wenn der Status javascript.0.anwesend gleich true ist und javascript.0.heizungssteuerung gleich
// true und wenn jetzt Sa. oder So. zwischen 06:00 u. 09:00 ist
// wenn Regel r1 nicht zutrifft, dann und nur dann wird r2 geprüft.
// regel r2 tritt ein, wenn der Status aus a (Status javascript.0.anwesend) und h (javascript.0.heizungssteuerung) wahr ist und
// die Uhrzeit + Datum Sa, So, zwischen 15.30 und 22:00 ist
// tritt die Regel r2 auch nicht ein, dann wird Regel r3 geprüft, usw.
// Trifft Regel r5 auch nicht zu, dann kommt Regel r6 ins Spiel und die trifft immer zu, da true. Sollte Regel r6 feheln,
// wird keine dern Regeln in query ausgeführt.
! rule: [ { name: "r1", query: "((a && h) && t1 && x)", id: idHeizung, value: 20.0 },
{ name: "r2", query: "((a && h) && t2 && y)", id: idHeizung, value: 19.0 },
{ name: "r3", query: "((b.value <> b.oldValue && !h)", id: idHeizung, value: 10 },
{ name: "r4", query: "((b.value <> b.oldValue && h)", id: idHeizung, value: function() { return 1+3; } },
{ name: "r5", query: "((b.value == b.oldValue && h)", id: idHeizung, value: 10, func: function(v) { log(v); } },
{ name: "r6", query: "true", id: idHeizung, value: 12 } ]};
! /
// **************************************************************************
// Dokumentation (Ende)
// **************************************************************************
! // **************************************************************************
// Globales Customizing (nicht loeschen)
// **************************************************************************
var instanz = "javascript.0."; // JavaInstanz
var ri = 0; // Zähler (nicht loeschen)
var task = []; // Regeln (nicht loeschen)
var sched = 15; // Regel wird alle sched Seku. ausgeführt (nicht loeschen)
var debug = false; // Debuging an/aus
! // **************************************************************************
// Eigene Funktionen für das Regelwerk, werden im
// Customizing genutzt (Vieles zum Testen)
// **************************************************************************
var funcWohnzimmer = function (value) { / logging("mein Test mit Value" + value); */ };
! var funcAbwesendAnAus = function() {var idSonnenaufgang = "javascript.0.Tageszeit.Sonnenaufgang"/*nächster Sonnenaufgang Uhrzeit*/; var idSonnenuntergang = "javascript.0.Tageszeit.Sonnenuntergang"/*nächster Sonnenuntergang Uhrzeit*/
! var vSonnenaufgang = getState(idSonnenaufgang).val;
var vSonnenuntergang = getState(idSonnenuntergang).val;
! // - 1 Std und + 3 Std.
var vSonnenaufgangAn = timeMinusTime(vSonnenaufgang,"00:15:00");
var vSonnenaufgangAus = timePlusTime(vSonnenaufgang,"02:00:00");
! // -1 Std und + 4 Std. und mindestens bis 23:10
var vSonnenuntergangAn = timeMinusTime(vSonnenuntergang,"01:00:00");
var vSonnenuntergangAus = timePlusTime(vSonnenuntergang,"04:00:00");
vSonnenuntergangAus = vSonnenuntergangAus < "23:00:00" ? "23:00:00" : vSonnenuntergangAus;logging("Licht an bei Abwesendheit von " + vSonnenaufgangAn + " bis " + vSonnenaufgangAus, true); logging("Licht an bei Abwesendheit von " + vSonnenuntergangAn + " bis " + vSonnenuntergangAus, true);
! var value1 = compareTime(vSonnenaufgangAn, vSonnenaufgangAus, "between");
var value2 = compareTime(vSonnenuntergangAn, vSonnenuntergangAus, "between");
! return ((value1 || value2) === true);}
! var funcLEDAnAus = function() {
! var idSonnenaufgang = "javascript.0.Tageszeit.Sonnenaufgang"/nächster Sonnenaufgang Uhrzeit/;
var idSonnenuntergang = "javascript.0.Tageszeit.Sonnenuntergang"/nächster Sonnenuntergang Uhrzeit/var vSonnenaufgang = getState(idSonnenaufgang).val; var vSonnenuntergang = getState(idSonnenuntergang).val; vSonnenuntergangAn = timeMinusTime(vSonnenuntergang,"00:45:00"); vSonnenuntergangAus = timePlusTime(vSonnenuntergang,"04:30:00"); vSonnenuntergangAus = vSonnenuntergangAus > "22:00:00" ? "22:00:00" : vSonnenuntergangAus; vSonnenuntergangAus = vSonnenuntergangAus < vSonnenuntergangAn ? "22:00:00" : vSonnenuntergangAus; vSonnenuntergangAn = vSonnenuntergangAn > vSonnenuntergangAus ? vSonnenuntergangAus : vSonnenuntergangAn; var value = compareTime(vSonnenuntergangAn, vSonnenuntergangAus, "between") logging("LED an um " + vSonnenuntergangAn + " bis " + vSonnenuntergangAus, true); return (value === true);
}
! // Beispiel
var funcLEDKette = function(value) {var on = value.on; var mode = value.mode; var idOn = "milight.0.zone1.state"/*Zone 1 Switch ON/OFF*/; var idMode = "milight.0.zone1.mode"/*Zone 1 mode*/; if(on) { if(getState(idOn).val != on) { setStateDelayed(idOn,on) }; if(getState(idMode) != mode) { setStateDelayed(idMode,2, 500) }; } else { if(getState(idOn).val != on) { setState(idOn,on) }; setState(idOn,false); }
};
! // **************************************************************************
// Eigenes Customizing (Anfang)
// **************************************************************************
var tempAbwesend = 16.0; // Temperatur wenn abwesend
var tempTuerAuf = 5.0; // Temperatur wenn Tür auf
var tempNachts = 16.5; // Temperatur Nachts
! var idWohnzimmer = "hm-rega.0.3143"/Temperatur Wohnzimmer/;
var idKueche = "hm-rega.0.3712"/Temperatur Küche/;
var idFlur = "hm-rega.0.8657"/Temperatur Flur EG/;
var idGaestebad = "hm-rega.0.4067"/Temperatur Gästebad/;
var idBadezimmer = "hm-rega.0.4068"/Temperatur Badezimmer/;
var idLinus = "hm-rega.0.8656"/Temperatur Linus/;
var idMaxi = "hm-rega.0.4159"/Temperatur Maxi/;
var idSchlafzimmer = "hm-rega.0.7738"/Temperatur Schlafzimmer/;
var idDachboden = "hm-rega.0.14450"/Temperatur Dachboden/;
var idTannebaumLicht = "sonoff.0.SONOFF_FLUR.POWER"/SONOFF_FLUR POWER/;
var idLichtAbwesend = "scene.Steckdosen_Alle";
var idLEDKette = "scene.LED_Lichterkette_2"/LED Lichterkette 2/;
! task[ri++] = {rulename: "Wohnzimmer", active: true, time: [ { name: "t1", from: "06:00", to: "22:00", weekday: "Mo,Di,Mi,Do" }, { name: "t2", from: "06:00", to: "23:00", weekday: "Fr" }, { name: "t3", from: "06:30", to: "23:00", weekday: "Sa" }, { name: "t4", from: "06:30", to: "22:00", weekday: "So" } ], state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/, value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true }, { name: "c1", id: "javascript.0.lupusec.devices.info1.status_ex"/*Wohnzimmer Links status_ex*/, value: 0 }, { name: "c2", id: "javascript.0.lupusec.devices.info2.status_ex"/*Wohnzimmer Rechts status_ex*/, value: 0 } ], rule: [ { name: "r1", query: "((a && h) && (t1 || t2 || t3 || t4) && (c1 && c2))", id: idWohnzimmer, value: 21, func: funcWohnzimmer }, { name: "r2", query: "((a && h) && (c1 && c2))", id: idWohnzimmer, value: tempNachts }, { name: "r3", query: "(h) && (!c1 || !c2)", id: idWohnzimmer, value: tempTuerAuf }, { name: "r4", query: "(!a && h)", id: idWohnzimmer, value: tempAbwesend } ] }
! task[ri++] = {
rulename: "Küche", active: true,
! time: [ { name: "t1", from: "06:00", to: "22:00", weekday: "" } ],
state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ , value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true }, { name: "c1", id: "javascript.0.lupusec.devices.1.info.status_ex"/*Küche Links status_ex*/, value: 0 }, { name: "c2", id: "javascript.0.lupusec.devices.2.info.status_ex"/*Küche Rechts status_ex*/, value: 0 } ],
!
rule: [ { name: "r1", query: "((a && h) && (t1) && (c1 && c2))", id: idKueche, value: 20.5 },
{ name: "r2", query: "((a && h) && (c1 && c2))", id: idKueche, value: tempNachts },
{ name: "r3", query: "(h) && (!c1 || !c2)", id: idKueche, value: tempTuerAuf },
{ name: "r4", query: "(!a && h)", id: idKueche, value: tempAbwesend } ]};
! task[ri++] = {
rulename: "Flur", active: true,
! time: [ { name: "t1", from: "06:00", to: "22:00", weekday: "" } ],
state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ , value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true }, { name: "c1", id: "javascript.0.lupusec.devices.1.info.status_ex"/*Haustür status_ex*/, value: 0 } ], rule: [ { name: "r1", query: "((a && h) && (t1) && (c1))", id: idFlur, value: 19.0 }, { name: "r2", query: "((a && h) && (c1))", id: idFlur, value: tempNachts }, { name: "r3", query: "(h) && (!c1)", id: idFlur, value: tempTuerAuf }, { name: "r4", query: "(!a && h)", id: idFlur, value: tempAbwesend } ] };
! task[ri++] = {
rulename: "Gästebad", active: true,
! time: [ { name: "t1", from: "06:00", to: "09:00", weekday: "Mo,Di,Mi,Do,Fr,Sa,So" },
{ name: "t2", from: "09:00", to: "15:00", weekday: "Sa,So" },
{ name: "t3", from: "09:00", to: "15:00", weekday: "Mo,Di,Mi,Do,Fr" },
{ name: "t4", from: "15:00", to: "22:00", weekday: "Mo,Di,Mi,Do,Fr,Sa,So" } ],state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ , value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true }, { name: "c1", id: "javascript.0.lupusec.devices.1.info.status_ex"/*Gästebad status_ex*/, value: 0 } ], rule: [ { name: "r1", query: "((a && h) && (t1 || t2 || t4) && (c1))", id: idGaestebad, value: 20.0 }, { name: "r2", query: "((a && h) && (t3) && (c1))", id: idGaestebad, value: 19.0 }, { name: "r3", query: "((a && h) && (c1))", id: idGaestebad, value: tempNachts }, { name: "r4", query: "(h) &&(!c1)", id: idGaestebad, value: tempTuerAuf }, { name: "r5", query: "(!a && h)", id: idGaestebad, value: tempAbwesend } ] };
! task[ri++] = {
rulename: "Badezimmer", active: true,
! time: [ { name: "t1", from: "05:30", to: "08:30", weekday: "Mo,Di,Mi,Do,Fr" },
{ name: "t2", from: "18:00", to: "22:00", weekday: "Mo,Di,Mi,Do,So" },
{ name: "t3", from: "07:00", to: "10:00", weekday: "Sa,So" },
{ name: "t4", from: "18:00", to: "23:00", weekday: "Fr,Sa" },
{ name: "t5", from: "08:30", to: "18:00", weekday: "Mo,Di,Mi,Do,Fr" },
{ name: "t6", from: "10:00", to: "18:00", weekday: "Sa,So" } ],state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ , value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true }, { name: "c1", id: "mihome.0.devices.magnet_123.state"/*Is opened*/, value: false } ], rule: [ { name: "r1", query: "((a && h) && (t1 || t2 || t3 || t4) && (c1))", id: idBadezimmer, value: 21.0 }, { name: "r2", query: "((a && h) && (t5 || t6) && (c1))", id: idBadezimmer, value: 20.0 }, { name: "r3", query: "((a && h) && (c1))", id: idBadezimmer, value: tempNachts }, { name: "r4", query: "(h) && (!c1)", id: idBadezimmer, value: tempTuerAuf }, { name: "r5", query: "(!a && h)", id: idBadezimmer, value: tempAbwesend } ] };
task[ri++] = {
rulename: "Linus", active: true,
! time: [ { name: "t1", from: "06:00", to: "22:00", weekday: "" } ],
state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ , value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true }, { name: "c1", id: "mihome.0.devices.magnet_123.state"/*Is opened*/, value: false }, { name: "c2", id: "mihome.0.devices.magnet_122.state"/*Is opened*/, value: false } ], rule: [ { name: "r1", query: "((a && h) && (t1) && (c1 && c2))", id: idLinus, value: 19.0 }, { name: "r2", query: "((a && h) && (c1 && c2))", id: idLinus, value: tempNachts }, { name: "r3", query: "(h) && (!c1 || !c2)", id: idLinus, value: tempTuerAuf }, { name: "r4", query: "(!a && h)", id: idLinus, value: tempAbwesend } ] };
! task[ri++] = {
rulename: "Maxi", active: true,
! time: [ { name: "t1", from: "06:00", to: "07:30", weekday: "Mo,Di,Mi,Do,Fr" },
{ name: "t2", from: "15:00", to: "22:00", weekday: "Mo,Di,Mi,Do,Fr" },
{ name: "t3", from: "06:30", to: "22:30", weekday: "Sa,So" },
{ name: "t4", from: "07:30", to: "15:00", weekday: "Mo,Di,Mi,Do,Fr" },
],state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ , value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true }, { name: "c1", id: "mihome.0.devices.magnet_12345.state"/*Is opened*/, value: false } ], rule: [ { name: "r1", query: "((a && h) && (t1 || t2 || t3) && (c1))", id: idMaxi, value: 20.0 }, { name: "r2", query: "((a && h) && (t4) && (c1))", id: idMaxi, value: 19.0 }, { name: "r3", query: "((a && h) && (c1))", id: idMaxi, value: tempNachts }, { name: "r4", query: "(h) && (!c1)", id: idMaxi, value: tempTuerAuf }, { name: "r5", query: "(!a && h)", id: idMaxi, value: tempAbwesend } ] };
task[ri++] = {
rulename: "Schlafzimmer", active: true,
! time: [ { name: "t1", from: "19:00", to: "22:00", weekday: "Mo,Di,Mi,Do,So" },
{ name: "t2", from: "19:00", to: "23:00", weekday: "Fr,Sa" },
{ name: "t3", from: "06:00", to: "07:30", weekday: "Mo,Di,Mi,Do,Fr" },
{ name: "t4", from: "10:30", to: "11:30", weekday: "Sa,So" },
{ name: "t5", from: "07:30", to: "19:00", weekday: "Mo,Di,Mi,Do,Fr" },
{ name: "t6", from: "11:30", to: "19:00", weekday: "Sa,So" },
],state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ , value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true }, { name: "c1", id: "mihome.0.devices.magnet_1223.state"/*Is opened*/, value: false }, { name: "c2", id: "mihome.0.devices.magnet_11223.state"/*Is opened*/, value: false }], rule: [ { name: "r1", query: "((a && h) && (t1 || t2 || t3 || t4) && (c1 && c2))", id: idSchlafzimmer, value: 20.0 }, // Morgens & Abends { name: "r4", query: "((a && h) && (t5 || t6) && (c1 && c2))", id: idSchlafzimmer, value: 18.0 }, // Tagsüber { name: "r2", query: "((a && h) && (c1 && c2))", id: idSchlafzimmer, value: 10.0 }, // Nachts { name: "r5", query: "(h) && (!c1 || !c2)", id: idSchlafzimmer , value: tempTuerAuf }, { name: "r3", query: "(!a && h)", id: idSchlafzimmer, value: tempAbwesend } ] // Abwesend };
! task[ri++] = {
rulename: "Dachboden", active: true,
! time: [ { name: "t1", from: "06:00", to: "22:00", weekday: "Mo,Di,Mi,Do,Fr" },
{ name: "t2", from: "06:30", to: "22:00", weekday: "Sa,So" } ],state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ , value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true } ], rule: [ { name: "r1", query: "((a && h) && (t1))", id: idDachboden, value: 19.0 }, // Zwischen 06:00-22:00 von Mo.-Fr. { name: "r2", query: "((a && h) && (t2))", id: idDachboden, value: 18.0 }, // Am Sa.-So. zwischen 06:30-22:00 { name: "r3", query: "((a && h))", id: idDachboden, value: 16.0 }, // Außerhalb der oberen Zeiten { name: "r4", query: "(!a && h)", id: idDachboden, value: tempAbwesend } ] // Wenn Abwesend };
!
task[ri++] = {rulename: "Tannenbaum", active: false,
! time: [ { name: "t1", from: "06:00", to: "09:00", weekday: "" },
{ name: "t2", from: "15:30", to: "22:00", weekday: "" } ],state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ , value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true } ], rule: [ { name: "r1", query: "(a) && (t1)", id: idTannebaumLicht, value: true }, // Zwischen 06:00-22:00 von Mo.-Fr. { name: "r2", query: true, id: idTannebaumLicht, value: false } ] // Sonst aus };
!
task[ri++] = {rulename: "Lichter An wenn Abwesend", active: true,
! time: [ { name: "t1", from: "00:00", to: "24:00", weekday: "", func: funcAbwesendAnAus } ],
state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true } ], rule: [ { name: "r1", query: "(!a.value) && (t1)", id: idLichtAbwesend, value: true }, { name: "r2", query: "(!a.value)", id: idLichtAbwesend, value: false }, // Sonst aus { name: "r3", query: "a.value && !a.oldValue", id: idLichtAbwesend, value: false } ] // Wenn Alarmanalage jetzt aus u. vorher an, dann Lichter aus };
! task[ri++] = {
rulename: "Test", active: true,
! time: [ { name: "t1", from: "00:00", to: "24:00", weekday: "", func: funcLEDAnAus } ], // Wichtig, ohne () bei funcLEDAnAus
state: [ { name: "a", id: "javascript.0.Apple.Alarm.anwesend"/*Anwesenheit*/ , value: true }, { name: "h", id: "javascript.0.Apple.Alarm.heizungssteuerung"/*Heizungssteuerung*/, value: true }, { name: "test", id: "hm-rpc.0.OEQ1111.4.SET_TEMPERATURE"/*Heizung Linus:4.ACTUAL_TEMPERATURE*/, value: 10 } ], rule: [ { name: "r1", query: "(a) && (t1)" , id: idLEDKette, value: true }, { name: "r2", query: "(a) && (!t1)", id: idLEDKette, value: false } ] // { name: "r1", query: "(a) && (t1)" , value: { on: true, mode: 2 } , func: funcLEDKette }, // { name: "r2", query: "(a) && (!t1)", value: { on: false }, func: funcLEDKette } ] // Sonst Licht Aus };
! // **************************************************************************
// Eigenes Customizing (Ende)
// **************************************************************************
! // *******************************************************************************
// Logging
// *******************************************************************************
function logging(text, deb = false) {if(deb === true) { if(debug === true) { console.log("Debug: " + text) } } else { console.log(text); }
}
! // *******************************************************************************
// Prüfen ob Objekt existiert um zu verhindern das bei getObject oder getState
// eine Warning ausgegeben wird.
// *******************************************************************************
function objectExsist(id) {var selector = $('state[state.id=' + id +']'); if(selector.length > 0) { return true; } else { return false; } logging("objectExsist // id: " + id + " // Length: " + selector.length, true);
}
! // **************************************************************************
// Wert als String darstellen, auch Objects und Arrays
// **************************************************************************
function valueToString(value) {var text = ""; var max; if(typeof value === "object") { var kind = Object.prototype.toString.call(value); // Create arrays of property names var vProps = Object.getOwnPropertyNames(value); if(kind === '[object Array]') { max = vProps.length - 1; } else { max = vProps.length; } for (var i = 0; i < max; i++) { var propName = vProps[i]; var propValue = value[propName]; if(i === 0) { text = propName + " = " + propValue; } else { text = text + ", " + propName + " = " + propValue + " "; } } } else { text = value; } return text;
}
! // **************************************************************************
// Sind 2 Werte gleich, egal welcher Typ
// **************************************************************************
function isEquivalent(a, b) {
! /*
if(typeof a !== typeof b) {
return false;
}
*/if(typeof a === "object" && typeof b === "object") {
// Create arrays of property names var aProps = Object.getOwnPropertyNames(a); var bProps = Object.getOwnPropertyNames(b); // If number of properties is different, // objects are not equivalent if (aProps.length != bProps.length) { return false; } for (var i = 0; i < aProps.length; i++) { var propName = aProps[i]; // If values of same property are not equal, // objects are not equivalent if (a[propName] !== b[propName]) { return false; } } // If we made it this far, objects // are considered equivalent return true;
} else {
return a == b ? true : false;
}
}
! // **************************************************************************
// Kopie von Objekten
// **************************************************************************
function copyObject(obj) {return JSON.parse(JSON.stringify(obj));
}
! // **************************************************************************
// Uhrzeit + Differenz. Bsp. 10:11:00 + 01:09:00 = 11:20:00
// **************************************************************************
function timePlusTime(t1, t2) {var d1 = new Date(Date.parse("01.11.1900 " + t1)); var d2 = new Date(Date.parse("01.11.1900 " + t2)); var dif = new Date(); dif.getHours(dif.setHours(d1.getHours() + d2.getHours())); dif.getMinutes(dif.setMinutes(d1.getMinutes() + d2.getMinutes())); dif.getSeconds(dif.setSeconds(d1.getSeconds() + d2.getSeconds()));
! return ((dif.getHours() < 10 ? '0' + dif.getHours() : + dif.getHours()) + ":" +
(dif.getMinutes() < 10 ? '0' + dif.getMinutes() : dif.getMinutes()) +":" +
(dif.getSeconds() < 10 ? '0' + dif.getSeconds() : dif.getSeconds())).toString();
!
}
! // **************************************************************************
// Uhrzeit - Differenz. Bsp. 10:11:00 - 01:10:00 = 09:01:00
// **************************************************************************
function timeMinusTime(t1, t2) {var d1 = new Date(Date.parse("01.11.1900 " + t1)); var d2 = new Date(Date.parse("01.11.1900 " + t2)); var dif = new Date(); dif.getHours(dif.setHours(d1.getHours() - d2.getHours())); dif.getMinutes(dif.setMinutes(d1.getMinutes() - d2.getMinutes())); dif.getSeconds(dif.setSeconds(d1.getSeconds() - d2.getSeconds()));
! return ((dif.getHours() < 10 ? '0' + dif.getHours() : + dif.getHours()) + ":" +
(dif.getMinutes() < 10 ? '0' + dif.getMinutes() : dif.getMinutes()) +":" +
(dif.getSeconds() < 10 ? '0' + dif.getSeconds() : dif.getSeconds())).toString();}
! // **************************************************************************
// Uhrzeit + 0 bis x Minuten (Zufall)
// **************************************************************************
function timePlusRadnomMinute(t1, t2) {
return timeRadnomMinute(t1, t2, "+");
}
! // **************************************************************************
// Uhrzeit - 0 bis x Minuten (Zufall)
// **************************************************************************
function timeMinusRadnomMinute(t1, t2) {
return timeRadnomMinute(t1, t2, "-");
}
! // **************************************************************************
// Uhrzeit +/- 0 bis x Minuten (Zufall)
// **************************************************************************
function timeRadnomMinute(t1, t2, p="+") {var d1 = new Date(Date.parse("01.11.1900 " + t1)); var randomMin = Math.floor(Math.random() * t2); var t; if(p == "+") { t = (1 * d1) + randomMin * 60 *1000; } else { t = (1 * d1) - randomMin * 60 *1000; } var d2 = new Date(t);
! return {
getHours: function(){
return d2.getHours();
},
getMinutes: function(){
return d2.getMinutes();
},
getSeconds: function() {
return d2.getSeconds();
},
toString: function(){
return ((this.getHours() < 10 ? "0" + this.getHours() : + this.getHours()) + ":" +
(this.getMinutes() < 10 ? "0" + this.getMinutes() : this.getMinutes()) +":" +
(this.getSeconds() < 10 ? "0" + this.getSeconds() : this.getSeconds()));
},
};
}
! // **************************************************************************
// im Urlaub
// **************************************************************************
function onVacation() {var idUrlaub = "feiertage.urlaub"; if(objectExsist(idUrlaub) === true) { var urlaub = getState(idUrlaub).val; return (urlaub == 1 ? true : false); } else { return false; }
}
! // **************************************************************************
// ist heute ein Feiertag
// **************************************************************************
function isHoliday() {
! var id = "feiertage.";
var now = new Date();
var day = now.getDate();
var month = now.getMonth() + 1;
var year = now.getFullYear();
! day = ((day < 10) ? "0" + day : day);
month = ((month < 10) ? "0" + month : month);var datum = year + "-" + month + "-" + day; var idFeiertag = id + year;
! var feiertag = getState(idFeiertag).val;
if(objectExsist(idFeiertag) === true) { var result = JSON.parse(feiertag); for(var i=0; i<result.length; i++/)/{/var/dat="result[i].date;" if(datum.indexof(dat)/!="-1" return/true;/}/false;/else/**************************************************************************/gibt/den/heutigen/wochentag/zurück/function/getwochentag()/d="new" date();/weekday="new" array(7);/weekday[0]="So" ;/weekday[1]="Mo" weekday[2]="Di" weekday[3]="Mi" weekday[4]="Do" weekday[5]="Fr" weekday[6]="Sa" weekday[d.getday()];/prüft/ob/der/heutige/tag/z.b./di/im/string/"mo,di,..."/erhalten/ist/iswochetag(wochentag)/if(typeof/"undefined"/||/"")/tmp="wochentag.toString().trim().replace(/(\r\n|\n|\r|\t|\s)/g,"");" wtag="tmp.split(',');" now="new" today="getWochentag();" holiday="isHoliday();" heute/ein/feiertag/urlaub="onVacation();" befinde/ich/mich/wenn/oder/dann/tun/wir/so/samstag/wäre/hd/vc/if(holiday="==" true/true)/for(var/i="0;" </wtag.length;/i++)/if(wtag[i]="=" today)/übergebene/wert/mit/dem/aktuellem/übereinstimmt,/wird/zurückgegeben/instate(id/,val)/value="getState(id).val;" isequivalent(value,val);/abbildung/eines/azzoativen/arrays/myarray()/arr="[];" obj="{};" getobj:/function(name,/key){/i</arr.length;/o="arr[i];" if(o.name="=" name/&&/o.key="=" key)/o;/},/getvalue:/key);/if(o/undefined)/push:/key,/value){/o.name="name;" o.value="value;" o.oldvalue="value;" arr.push(o);/};/lesen/werte/inkl./speichern/von/alten/werten/getownstate(rulename,/name,/id)/if/(getownstate.array="==" getownstate.array="MyArray();" getownstate.array.push(rulename,name,/getstate(id).val);/obj.value="getOwnState.array.getValue(rulename,name).value;" obj.oldvalue="getOwnState.array.getValue(rulename,name).oldValue;" logging("rulename:/"/+/rulename/name:/id:/id/value:/obj.value,/true);/oldvalue:/obj.oldvalue,/obj;/prüfen/uhrzeit/zwischen/start/und/ende/zeit/liegt./bsp./mi/,/09:00/intime("08:00","10:00","mo,mi,fr")/wahr/intime(start,ende,/"between")/iswochetag(wochentag);/(value="==" evalrule(regeleval,/b)/regeleval.length;/if(regeleval[i].query="==" if(b.regel/b.regel="i;" b.value="regelEval[i].value;" b;/keine/passende/regel/gefunden./objekt/passen/nicht/an,/aber/setzen/wieder/auf/-1/nichts/gefunden/undefined/evalstatement(obj)/i,o;/tmp;/regeleval="[];" b="{};" fret;/element/time/in/for(i="0;" i<obj.time.length;/if(!o.hasownproperty("from"))/o.from="00:00" if(!o.hasownproperty("to"))/o.to="24:00" if(!o.hasownproperty("weekday"))/o.weekday/if(!o.hasownproperty("func"))/o.func="function()" "','"/"')/o.func();/eval(tmp);/state/i<obj.state.length;/switch(typeof/o.value)/case/"boolean":/v="o.value;" o.id/"',"/")";/break;/"number":/"function":/"undefined":/ot="getOwnState(obj.rulename," o.name,/o.id);/";/".value=" + ot.value + " ".oldvalue=" + ot.oldValue + " "string":/"'";/default:/rule/i<obj.rule.length;/regeleval[i]="{" query:/eval(o.query),/o.id,/func:/o.func,/"function")/funktion/ausführen/regeleval[i].value="o.value();" übernehmen/ersten/durchgang/noch/leer/b);/obj.regel="b.regel;" des/regelewerks/controler()/evalruleobj(obj)/setvaluesbyobj(obj)/if(obj.active)/"undefined")/func="obj.rule[obj.regel].func;" logtext="obj.rulename" valuetostring(obj.value)/regel:/obj.rule[obj.regel].name.touppercase();/logging(logtext);/einer/udn/gesetzt/kein/typeof/"object")/if(getstate(id).val/setstate(id,/obj.value);/steht/func(obj.value);/onstatesetzen(obj)/logging("onstatesetzen/listen/on/state:/for/rule:/obj.rulename,/on({/id,/change:/'ne'},/(o)/setvaluesbyobj(obj);/});/start()/objects="task;" i<objects.length;/onstatesetzen(obj);/schedule("*/sched/*/*",/function()/logging("start/regelwerk/ausgeführt",/start();/controler();/<e=""></result.length;>`
! Ich bin nicht der große JavaScript Entwickler und habe gerade mal 2-3 Monate Erfahrung gesammelt. Also, falls Ihr Fehler findet, bitte kurze Info an mich. Das gilt natürlich auch für Verbesserungsvoschläge.
! Gruß
! Stübi[/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i] -
danke für teilen mit der community! Nur als frage: das heizungsscript von Looxer hat deinen Anforderungen nicht entsprochen ?
-
danke für teilen mit der community! Nur als frage: das heizungsscript von Looxer hat deinen Anforderungen nicht entsprochen ? `
ich hatte vorher die komplette Heizungssteuerung auf der Homematic CCU2 abgebildet. Mir gefiel auf der CCU wie man Regeln (Bedingungen) abbilden konnte. Das habe ich für meine Bedürfnisse auf dem ioBroker mit dem JavaScript übernommen