Heizungsthermostatscript V2.0
Das Heizungsscript stammt ursprünglich aus der Feder von erik und wurde seitdem u.a. von Petrus und MartinS verbessert:
http://homematic-forum.de/forum/viewtop ... 60#p142493
Es gibt in dem Forenthema noch andere Varianten des Heizungsscripts. Ich selber nutze aber nur noch diese Variante. Ich habe die tmp-Variablen nochmal durchgesehen und neu ersetzt. Nun sollten keine anderen Variablennamen mehr vorhanden sein, außer die tmp-Variablen. Ein Testlauf verlief bei mir ohne Probleme.
Hier nun meine tmp-Variablen-Variante:
Code: Alles auswählen
string tmpA = "Zimmer" ; ! Zimmer-Name
! Version 2.0
! Script von Erik Groennerud - 8.2009- MM.2013
! Ergaenzung von Zauberlehrling
! Optimiert und ergaenzt von Petrus (Peter)
! Performance Ideen von Goersch
! Ergaenzungen von Martin Schneider
! tmp-Variablen-Umschreibung von Tharanis
! Definition Thermostat - Abfrage/Setzen der Temperatur: BidCos-RF.<SERIENNUMMER>:<KANALNUMMER>.<DATENPUNKT>
! HM-CC-TC BidCos-RF.<SERIENNUMMER>:2.SETPOINT
! HM-CC-RT-DN BidCos-RF.<SERIENNUMMER>:4.SET_TEMPERATURE
! HM-TC-IT-WM-W-EU BidCos-RF.<SERIENNUMMER>:2.SET_TEMPERATURE
string tmpB = "BidCos-RF.JEQ0123456:2.SETPOINT";
! Definition Sensoren: BidCos-RF.<SERIENNUMMER>:<KANALNUMMER>.<DATENPUNKT>
! HM-Sec-SC-2 BidCos-RF.<SERIENNUMMER>:1.STATE
! Hier koennen 0 bis n-Geraete rein - mit ";" trennen oder "" fuer kein Geraet (ohne Leerzeichen)
string tmpC = "BidCos-RF.KEQ0123456:1.STATE;BidCos-RF.KEQ7654321:1.STATE";
! Temperaturen 6-30 Grad, 0 = OFF, 100=ON
real tmpD = 18.0; ! grad_0
real tmpE = 19.0; ! grad_1
real tmpF = 19.5; ! grad_2
real tmpG = 20.0; ! grad_3
real tmpH = 20.5; ! grad_4
real tmpI = 21.0; ! grad_5
real tmpJ = 21.5; ! grad_6
real tmpK = 22.0; ! grad_7
real tmpL = 22.5; ! grad_8
real tmpM = 23.0; ! grad_9
real tmpN = 6; ! Temperatur bei offenem Fenster -1 = off - Grad_fenster
real tmpO = 18; ! Temperatur im Urlaub -1 = off - Grad_urlaub
real tmpP = 18.5; ! Temperatur fuer Gaeste -1 = off - Grad_gaeste
real tmpQ = 18; ! Temperatur ausser haus, wird als Absenkung benutzt, -1 = OFF (immer Anwesenheit) - tmpQ
string tmpR = "02:00"; ! tmpR mit "hh:mm" setzten (Std / Min immer zweistellig) Differenzzeit, die manuelle Temperatur erhalten bleibt bis ueberschrieben wird
integer tmpS = 0; ! 0=7 Tage Woche, 1=Montag=Wochentags & Samstag=Wochenende, 2= Montag=Woche, 3=Montag=Wochentags & Samstag=Samstag & Sonntag=Sonntag
integer tmpT = 1; ! Welche Zeitleiste aktiv ist
if (tmpT == 1){
! Zeitleiste 1
! Uhrzeit 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2|
! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3|
string tmpA2 = "000000000000000000000000000000000033355555555330"; ! Zeitleiste Montag
string tmpB2 = "000000000000000000000000000000000033355555555330"; ! Zeitleiste Dienstag
string tmpC2 = "000000000000000000000000000000000033355555555330"; ! Zeitleiste Mittwoch
string tmpD2 = "000000000000000000000000000000000033355555555330"; ! Zeitleiste Donnerstag
string tmpE2 = "000000000000000000000000000022335555555555555330"; ! Zeitleiste Freitag
string tmpF2 = "000000000000113335555555553355555555555555544433"; ! Zeitleiste Samstag
string tmpG2 = "000000000000113335555555553355555555555555544433"; ! Zeitleiste Sonntag
};
if (tmpT == 2){
! Zeitleiste 2
! Uhrzeit 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2|
! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3|
string tmpA2 = "000000000000000000000000000000000033355555555330"; ! Zeitleiste Montag
string tmpB2 = "000000000000000000000000000000000033355555555330"; ! Zeitleiste Dienstag
string tmpC2 = "000000000000000000000000000000000033355555555330"; ! Zeitleiste Mittwoch
string tmpD2 = "000000000000000000000000000000000033355555555330"; ! Zeitleiste Donnerstag
string tmpE2 = "000000000000000000000000000022335555555555555330"; ! Zeitleiste Freitag
string tmpF2 = "000000000000113335555555553355555555555555544433"; ! Zeitleiste Samstag
string tmpG2 = "000000000000113335555555553355555555555555544433"; ! Zeitleiste Sonntag
};
boolean tmpU = 0; ! Debug Infos ins Syslog - sollte immer auf 0 sein, nur bei Problemen auf 1
!******************************************************
! Ab hier Script CODE - Do not change behind this line
!******************************************************
! Umwandeln tmpR in Sekunden
integer tmpV = tmpR.Substr(0, 2).ToInteger();
integer tmpW = tmpR.Substr(3, 2).ToInteger();
integer tmpX = (tmpV * 3600) + (tmpW * 60);
! SN aus tmpB bestimmen
string tmpY = tmpB.Substr(10, (tmpB.Find(":") - 10));
object tmpZ; ! Datenobjekt des Reglers fuer die Solltemperatur (Kanal 2)
real tmpA1; ! Die neue Solltemperatur fuer den Raumthermostaten (Regler).
real tmpB1; ! Die alte Solltemperatur der Zeitleiste, die zuletzt aktuell war.
real tmpC1 = -1; ! Die aktuelle Solltemperatur im Raumthermostat (Regler).
time tmpD1; ! Zeitstempel der Systemvariablen, die zuletzt geaendert worden ist (Wert in Sekunden).
time tmpE1; ! Zeitstempel, wann die Solltemperatur im RT zuletzt gesetzt wurde.
boolean tmpF1 = false; ! Ist tmpF1 = true, dann wird die neue Solltemperatur auf jeden Fall in den Regler geschrieben. Prioritaet
!Wenn keine Heizperiode, dann Heizkoerper auf - Bei Einsatz von HM-CC-RT-DN muss der tmpA1-Wert auf 30 gesetzt werden, sonst gibt es einen zu hohen Duty-Cycle
if (dom.GetObject('Heizperiode').State()) {
tmpA1 = 100;
tmpF1 = true;
! Aktuelle Solltemperatur auslesen
object tmpZ = dom.GetObject(tmpB);
tmpC1 = tmpZ.Value();
} else {
integer tmpG1 = 0;
tmpZ = dom.GetObject(tmpB);
tmpC1 = tmpZ.Value();
if ( tmpC != "" ) {
string tmpH1;
foreach (tmpH1,tmpC.Split(";")) {
object tmpI1 = dom.GetObject(tmpH1);
if (tmpI1.State() > 0) {
tmpG1 = tmpG1 + 1.00;
}
}
}
! Wenn ein Verschluss im Raum offen ist, dann Fenstertemperatur einstellen
if (tmpG1 > 0) { ! Fenster offen, Ventile einstellen
if (tmpC1 <= tmpN) { ! Wenn tmpC1 niedriger als tmpN (z.B. Ventile zu -> tmpC1 = 0), dann nichts machen
tmpA1 = tmpC1;
} else {
tmpA1 = tmpN;
tmpF1 = true;
}
} else {
! Timestamp "Partytemperatur" festhalten
tmpD1 = dom.GetObject('Partytemperatur').Timestamp();
! Partytemperatur testen und einstellen, -1 = deaktiviert
integer tmpJ1 = dom.GetObject('Partytemperatur').State();
if (tmpJ1 > -1) { !Wenn Partytemperatur, dann einstellen
tmpA1 = tmpJ1;
} else {
! Pruefen ob Timestamp "Urlaub" juenger ist als "Partytemperatur" => Wenn ja, merken
time tmpK1 = dom.GetObject('Urlaub').Timestamp();
if (tmpK1 > tmpD1) {tmpD1 = tmpK1;}
! Urlaub testen und einstellen, -1 = deaktiviert
if ((dom.GetObject('Urlaub').State()) && (tmpO > -1)) { !Wenn im Urlaub und tmpO nicht -1 (deaktiviert)
tmpA1 = tmpO;
} else {
! Pruefen ob Timestamp "Gaeste" juenger ist als "Urlaub" => Wenn ja, merken
tmpK1 = dom.GetObject('Gaeste').Timestamp();
if (tmpK1 > tmpD1) {tmpD1 = tmpK1;}
! Gaeste testen und einstellen, -1 = deaktiviert
if ((dom.GetObject('Gaeste').State()) && (tmpP > -1)){ !Wenn Gaeste im Haus und tmpP nicht -1 (deaktiviert)
tmpA1 = tmpP;
} else {
! Pruefen ob Timestamp "Anwesenheit" juenger ist als "Gaeste" => Wenn ja, merken
tmpK1 = dom.GetObject('Anwesenheit.Heizung').Timestamp();
if (tmpK1 > tmpD1) {tmpD1 = tmpK1;}
! Differenzen von ausser Haus Testen und beachten
if ((!dom.GetObject('Anwesenheit.Heizung').State()) && (tmpQ > -1)) {
tmpA1 = tmpQ;
} else {
string tmpL1; ! Die Temperaturleiste fuer den aktuellen Tag. Zeitleiste heute
string tmpM1; ! Die Temperaturleiste von gestern. Zeitleiste gestern
string tmpN1; ! Enthaelt den Wert, der in der Zeitleiste zum jetzigen Zeitpunkt gilt. heizwert
! Hier nun die Auswertung der Zeitleisten
!Auswerten, welche Zeitleiste heute ist
integer tmpO1 = system.Date("%u");
if ((tmpO1 == 1) && (tmpS == 0)) {tmpL1 = tmpA2;} else {
if ((tmpO1 == 2) && (tmpS == 0)) {tmpL1 = tmpB2;} else {
if ((tmpO1 == 3) && (tmpS == 0)) {tmpL1 = tmpC2;} else {
if ((tmpO1 == 4) && (tmpS == 0)) {tmpL1 = tmpD2;} else {
if ((tmpO1 == 5) && (tmpS == 0)) {tmpL1 = tmpE2;} else {
if ((tmpO1 == 6) && ((tmpS == 0) || (tmpS == 3))) {tmpL1 = tmpF2;} else {
if ((tmpO1 == 7) && ((tmpS == 0) || (tmpS == 3))) {tmpL1 = tmpG2;} else {
if ((tmpO1 >= 1) && (tmpO1 <= 5) && ((tmpS == 1) || (tmpS == 3))) {tmpL1 = tmpA2;} else {
if ((tmpO1 >= 6) && (tmpO1 <= 7) && (tmpS == 1)) {tmpL1 = tmpF2;} else {
if (tmpS == 2) {tmpL1 = tmpA2;} }}}}}}}}}
! An Feiertagen gilt die Temperatur von Samstag bzw. Sonntag
if (dom.GetObject('Feiertag').State() && ((tmpS == 0) || (tmpS == 3))) {tmpL1 = tmpG2;} else {
if (dom.GetObject('Feiertag').State() && (tmpS == 1)) {tmpL1 = tmpF2;}}
! Position der Zeitleiste bestimmen
if (system.Date("%M").ToInteger() > 29) {integer tmpP1 = 1;} else {integer tmpP1 = 0;}
integer tmpQ1 = (system.Date("%H").ToInteger()*2)+tmpP1;
tmpN1 = tmpL1.Substr(tmpQ1, 1);
! Temperatur bestimmen, die gesetzt werden soll
if (tmpN1 == "0") {tmpA1 = tmpD;} else {
if (tmpN1 == "1") {tmpA1 = tmpE;} else {
if (tmpN1 == "2") {tmpA1 = tmpF;} else {
if (tmpN1 == "3") {tmpA1 = tmpG;} else {
if (tmpN1 == "4") {tmpA1 = tmpH;} else {
if (tmpN1 == "5") {tmpA1 = tmpI;} else {
if (tmpN1 == "6") {tmpA1 = tmpJ;} else {
if (tmpN1 == "7") {tmpA1 = tmpK;} else {
if (tmpN1 == "8") {tmpA1 = tmpL;} else {
if (tmpN1 == "9") {tmpA1 = tmpM;} }}}}}}}}}
! letzte Solltemeratur bestimmen, dabei muss der wert von 00:00 beachtet werden - der letzte Wert war gestern
if (tmpQ1 == 0) {
if ((tmpO1 == 1) && ((tmpS == 0) || (tmpS == 3))) {tmpM1 = tmpG2;} else {
if ((tmpO1 == 2) && (tmpS == 0)) {tmpM1 = tmpA2;} else {
if ((tmpO1 == 3) && (tmpS == 0)) {tmpM1 = tmpB2;} else {
if ((tmpO1 == 4) && (tmpS == 0)) {tmpM1 = tmpC2;} else {
if ((tmpO1 == 5) && (tmpS == 0)) {tmpM1 = tmpD2;} else {
if ((tmpO1 == 6) && (tmpS == 0)) {tmpM1 = tmpE2;} else {
if ((tmpO1 == 7) && ((tmpS == 0) || (tmpS == 3))) {tmpM1 = tmpF2;} else {
if ((tmpO1 >= 2) && (tmpO1 <= 6) && ((tmpS == 1) || (tmpS == 3))) {tmpM1 = tmpA2;} else {
if (((tmpO1 == 1) || (tmpO1 == 7)) && (tmpS == 1)) {tmpM1 = tmpF2;} else {
if (tmpS == 2) {tmpM1 = tmpA2;} }}}}}}}}}
tmpN1 = tmpM1.Substr(47, 1);
} else {
tmpN1 = tmpL1.Substr((tmpQ1-1), 1);
}
! Temperatur bestimmen, die in der letzten 30 Minutenn war
if (tmpN1 == "0") {tmpB1 = tmpD;} else {
if (tmpN1 == "1") {tmpB1 = tmpE;} else {
if (tmpN1 == "2") {tmpB1 = tmpF;} else {
if (tmpN1 == "3") {tmpB1 = tmpG;} else {
if (tmpN1 == "4") {tmpB1 = tmpH;} else {
if (tmpN1 == "5") {tmpB1 = tmpI;} else {
if (tmpN1 == "6") {tmpB1 = tmpJ;} else {
if (tmpN1 == "7") {tmpB1 = tmpK;} else {
if (tmpN1 == "8") {tmpB1 = tmpL;} else {
if (tmpN1 == "9") {tmpB1 = tmpM;} }}}}}}}}}
} !Ende IF Anwesenheit
} !Ende IF Gaeste
} !Ende IF Urlaub
} !Ende IF Partytemperatur
} !Ende IF Fenster offen
} !Ende IF Heizungsperiode
if (tmpC1 >= 0) { ! Wenn RT geantwortet hat (Sollwert konnte ausgelesen werden)...
! Workaround fuer automatisches setzen der Zeitstempel im Thermostat
! Es wird nur noch eine Systemvariable "LastChg_LEQxxxxxxx" vom Typ Zeichenkette verwendet.
var tmpR1 = dom.GetObject('LastChg_' # tmpY);
time tmpS1;
real tmpT1 = -1;
if (tmpR1 != null) {
string tmpU1 = tmpR1.Variable();
if (tmpU1.Find(";") >= 0) {
tmpS1 = tmpU1.StrValueByIndex(";", 0).ToTime();
tmpT1 = tmpU1.StrValueByIndex(";", 1).ToFloat();
}
if (tmpC1 != tmpT1) {
! Temperatur wurde manuell verstellt, neu abspeichern
tmpU1 = system.Date("%Y-%m-%d %H:%M:%S") # ";" # tmpC1.ToString();
tmpR1.Variable(tmpU1);
tmpS1 = tmpU1.StrValueByIndex(";", 0).ToTime();
tmpT1 = tmpU1.StrValueByIndex(";", 1).ToFloat();
}
}
! ...dann pruefen ob neue Solltemperatur in RT geschrieben werden muss.
if (tmpC1 <> tmpA1) { ! Wenn aktuelle Solltemperatur = neue Solltemp., dann nichts machen
tmpZ = dom.GetObject(tmpB);
time tmpV1 = system.Date("%Y-%m-%d %H:%M:%S").ToTime(); ! wie spaet ist es jetzt?
if (tmpR1 != null) {
tmpE1 = tmpS1;
} else {
tmpE1 = tmpZ.Timestamp();
}
integer tmpW1 = tmpV1.ToInteger() - tmpE1.ToInteger();
if ((tmpW1 >= tmpX) || (tmpF1) || (tmpC1 == tmpN) || (tmpD1 >= tmpE1) || ((tmpC1 == tmpB1) && (tmpB1 <> tmpA1))) {
! Temperatur setzen
tmpZ.State(tmpA1);
! Abspeichern der neuen Soll-Temperatur zum Vergleich bei manueller Aenderung.
! Alten Zeitstempel und nicht den aktuellen verwenden, da sonst Probleme mit tmpW1/tmpX
if (tmpR1 != null) {
tmpR1.Variable('2010-01-01 00:00:00' # ';' # tmpA1.ToString());
}
integer tmpX1 = 1;
if (tmpU) {
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("logger -t script -p user.tmpU Raumthermostat " # tmpA # " neu gesetzt!\n");
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("logger -t script -p user.tmpU alte_Solltemperatur: " # tmpC1 # " neue_Solltemperatur: " # tmpA1 # "\n");
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("logger -t script -p user.tmpU Letzte_Aenderung: " # tmpE1 # " Zeitdifferenz:_" # tmpW1 # "sek.");
}
}
}
} else {
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("logger -t script -p user.tmpU Raumthermostat " # tmpA # " antwortet nicht!");
}
Im Vergleich zur Version von MartinS sind bei dieser Version die System.exec-Befehle durch CuxD ersetzt.
Ich habe bei den Zeitleisten extra einen Sprung in der Reihenfolge der Variablenbenennung gemacht, damit die Zeitleisten nicht durch unterschiedlich lange Variablennamen schwerer lesbar sind. Die Reihenfolge der Variablennamen greife ich danach wieder auf.
EDIT: Ich habe im Script die Systemvariable "Anwesenheit" in "Anwesenheit.Heizung" geändert. Bei mir hat das den Hintergrund, dass ich eine TRennung von der normalen Abwesenheit haben wollte, aber trotzdem die Heizung auf Abwesend stellen können wollte. In den Originalscripten heisst die Systemvariable aber "Anwesenheit".