Sodale, Winter ist, warm ist. Glaub hab das ganze Zeugs seit 3 Jahren, immer wieder mal gibts den 4% Bug. (Vorraum FKK taugliche 26,9 C hehe, eh gemütlich, wären da nicht die Kosten)
Jetzt hab ich mich mal wieder hingesetzt und Eriks berühmtes Heizungsscript überarbeitet und eine Performante Version aus 1.7.2 und 2.0 erstellt, welche den 4% Bug abfängt. Und - es funktioniert!
Was hab ich:
Alle Thermostate HM-CC-TC haben eine V2.0 Firmware.
Alle Stellantriebe HM-CC-VD haben eine V1.8 Firmware. <= Hab ich lieber als den 0% Bug von V2.0.
Was mach ich:
- Script um einlesen der Ist Temperatur und des Stellgrades erweitert.
- Wenn Ist >= Soll + Offset und Stellgrad > 0 dann Soll Neu = 0
- Offset ist bei mir 0,5 C
Damit überregeln die Thermostate nicht mehr ins unendliche.
Beim schnellen Aufheizen überschwingt die Ist Temp je nach Raumgröße um 0,5 - 1 C, hört dann aber zuverlässig zum Heizen auf und schwingt sich ein auf denn Soll Wert.
Laufen lass ich das Script alle 15 min für 5 Räume, wie man es richtig aufruft, bitte beim Heizungsscript Thread nachschauen.
Kernabfrage:
Code: Alles auswählen
! 4 % Bug check, Ist Temperatur muss größer als Fenster offentemperatur sein
if (ist_temp >= grad_fenster) {
if ((ist_temp >= soll_neu + grad_offs) && (ist_temp >= soll_ist + grad_offs)) {
if (stell_grad > 0) {
soll_neu = 0;
! gewährleistet, dass regler.State auf soll_neu gesetzt wird
soll_ist = 0.1;
prioritaet = true;
}
}
}
Ich frag hier zusätzlich noch einen Temp. Aussensensor ab, kann man ausbauen.
Bei IEQ00XXXXX,IEQ00YYYYY.... natürlich die eigenen Seriennummern raussuchen.
Ich verwende in dem Beispiel auch zwei Fensterdrehkontakte.
Code: Alles auswählen
string raum = "Schlafzimmer";
boolean debug = 0; ! Debug Infos ins Syslog
! Version 1.8.0
! Speedoptimiert,4% Bug Basis Eriks Heizungsscript 1.7.2,2.0
string sAussensensor = "IEQ00XXXXX";
! Raumspezifische Variablen
string sRegler = "IEQ00YYYYY"; ! Definition des Thermostates
string sVentil = "IEQ00ZZZZZ"; ! Definition des Ventils
! hier können 0 bis n-Geräte rein - mit ";" trennen oder "" fuer kein Geraet (ohne Leerzeichen)
string sTuerenUndFenster = "BidCos-RF.IEQ00AAAAA:1.STATE;BidCos-RF.IEQ00BBBBB:1.STATE";
! Zeitleiste
! 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 zeitleiste_mon = "111111111111111111111111333333333333333333333333";
string zeitleiste_die = "111111111111111111111111333333333333333333333333";
string zeitleiste_mit = "111111111111111111111111333333333333333333333333";
string zeitleiste_don = "111111111111111111111111333333333333333333333333";
string zeitleiste_fre = "111111111111111111111111333333333333333333333333";
string zeitleiste_sam = "111111111111111111111111333333333333333333333333";
string zeitleiste_son = "111111111111111111111111333333333333333333333333";
real grad_offs = 0.5; ! Temperatur offset fuer 4 % Bug
object regler; ! Datenobjekt des Reglers für die Solltemperatur (Kanal 2)
object regler1; ! Datenobjekt des Reglers für die Isttemperatur (Kanal 1)
object ventil; ! Datenobjekt des Ventils für den Stellgrad (Kanal 1)
object aussensensor; ! Datenobjekt des Aussensensors für die Temperatur (Kanal 1)
real soll_ist = -1; ! Die aktuelle Solltemperatur im Raumthermostat (Regler).
real ist_temp; ! Die aktuelle Isttemperatur im Raumthermostat (Regler).
real aussen_temp = -100; ! Die aktuelle Außentemperatur
real soll_neu; ! Die neue Solltemperatur fuer den Raumthermostaten (Regler).
real soll_alt; ! Die alte Solltemperatur der Zeitleiste, die zuletzt aktuell war.
time sv_timestamp; ! Zeitstempel der Systemvariablen, die zuletzt geändert worden ist (Wert in Sekunden).
time rt_timestamp; ! Zeitstempel, wann die Solltemperatur im RT zuletzt gesetzt wurde.
boolean prioritaet = false; ! Ist prioritaet = true, dann wird die neue Solltemperatur auf jeden Fall in den Regler geschrieben.
integer offen = 0;
integer stell_grad = 0;
! Temperaturen 8-30 Grad, 0 = OFF, 100=ON
real grad_0 = 19;
real grad_1 = 20.5;
real grad_2 = 21.0;
real grad_3 = 21.5;
real grad_4 = 22.5;
real grad_5 = 23;
real grad_6 = 25;
real grad_7 = 27;
real grad_8 = 0;
real grad_9 = 100;
real grad_fenster = 12; ! Temperatur bei offenem Fenster -1 = off
real grad_urlaub = 16; ! Temperatur im Urlaub -1 = off
real grad_gaeste = 22; ! Temperatur fuer Gaeste -1 = off
real grad_aa = 18.5; ! Temperatur ausser haus, wird als Absenkung benutzt, -1 = OFF (Anwesenheit)
string deltaStdMin = "02:00"; ! deltaStdMin mit "hh:mm" setzten (Std / Min immer zweistellig) Differenzzeit, die manuelle Temperatur erhalten bleibt bis überschrieben wird.
integer woche = 0; ! 0=7 Tage Woche, 1=Montag=Wochentags & Samstag=Wochenende, 2= Montag=Woche, 3=Montag=Wochentags & Samstag=Samstag & Sonntag=Sonntag
! Umwandeln deltaStdMin in Sekunden
integer stunde = deltaStdMin.Substr(0, 2).ToInteger();
integer minute = deltaStdMin.Substr(3, 2).ToInteger();
integer setdelta = (stunde * 3600) + (minute * 60);
! Fetch datapoints
regler = dom.GetObject("BidCos-RF." # sRegler # ":2.SETPOINT");
soll_ist = regler.Value();
regler1 = dom.GetObject("BidCos-RF." # sRegler # ":1.TEMPERATURE");
ist_temp = regler1.Value();
ventil = dom.GetObject ("BidCos-RF." # sVentil # ":1.VALVE_STATE");
stell_grad = ventil.Value();
aussensensor = dom.GetObject("BidCos-RF." # sAussensensor # ":1.TEMPERATURE");
aussen_temp = aussensensor.Value();
if ( sTuerenUndFenster != "" )
{
string value;
foreach (value,sTuerenUndFenster.Split(";"))
{
object myChannel = dom.GetObject(value);
if (myChannel.State() > 0)
{
offen = offen + 1;
}
}
}
!Wenn keine Heizperiode, dann Heizkörper auf
if (!dom.GetObject('Heizperiode').State()) {
soll_neu = 100;
prioritaet = true;
} else {
! Wenn ein Verschluss im Raum offen ist, dann Fenstertemperatur einstellen
if (offen > 0) { ! Fenster offen, Ventile einstellen
if (soll_ist <= grad_fenster) { ! Wenn soll_ist niedriger als grad_fenster (z.B. Ventile zu -> soll_ist = 0), dann nichts machen
soll_neu = soll_ist;
} else {
soll_neu = grad_fenster;
prioritaet = true;
}
} else {
! Timestamp "Partytemperatur" festhalten
sv_timestamp = dom.GetObject('Partytemperatur').Timestamp();
! Partytemperatur testen und einstellen, -1 = deaktiviert
integer partytemperatur = dom.GetObject('Partytemperatur').State();
if (partytemperatur > -1) { !Wenn Partytemperatur, dann einstellen
soll_neu = partytemperatur;
} else {
! Prüfen ob Timestamp "Urlaub" jünger ist als "Partytemperatur" => Wenn ja, merken
time settime = dom.GetObject('Urlaub').Timestamp();
if (settime > sv_timestamp) {sv_timestamp = settime;}
! Urlaub testen und einstellen, -1 = deaktiviert
if ((dom.GetObject('Urlaub').State()) && (grad_urlaub > -1)) { !Wenn im Urlaub und grad_urlaub nicht -1 (deaktiviert)
soll_neu = grad_urlaub;
} else {
! Prüfen ob Timestamp "Gaeste" jünger ist als "Urlaub" => Wenn ja, merken
settime = dom.GetObject('Gaeste').Timestamp();
if (settime > sv_timestamp) {sv_timestamp = settime;}
! Gaeste testen und einstellen, -1 = deaktiviert
if ((dom.GetObject('Gaeste').State()) && (grad_gaeste > -1)){ !Wenn Gaeste im Haus und grad_gaeste nicht -1 (deaktiviert)
soll_neu = grad_gaeste;
} else {
! Prüfen ob Timestamp "Anwesenheit" jünger ist als "Gaeste" => Wenn ja, merken
settime = dom.GetObject('Anwesenheit').Timestamp();
if (settime > sv_timestamp) {sv_timestamp = settime;}
! Differenzen von außer Haus Testen und beachten
if ((!dom.GetObject('Anwesenheit').State()) && (grad_aa > -1)) {
soll_neu = grad_aa;
} else {
string zeitleiste_heute; ! Die Temperaturleiste fuer den aktuellen Tag.
string zeitleiste_gestern; ! Die Temperaturleiste von gestern.
string heizwert; ! Enthaelt den Wert, der in der Zeitleiste zum jetzigen Zeitpunkt gilt.
! Hier nun die Auswertung der Zeitleisten
!Auswerten, welche Zeitleiste heute ist
integer tag = system.Date("%u");
if ((tag == 1) && (woche == 0)) {zeitleiste_heute = zeitleiste_mon;} else {
if ((tag == 2) && (woche == 0)) {zeitleiste_heute = zeitleiste_die;} else {
if ((tag == 3) && (woche == 0)) {zeitleiste_heute = zeitleiste_mit;} else {
if ((tag == 4) && (woche == 0)) {zeitleiste_heute = zeitleiste_don;} else {
if ((tag == 5) && (woche == 0)) {zeitleiste_heute = zeitleiste_fre;} else {
if ((tag == 6) && ((woche == 0) || (woche == 3))) {zeitleiste_heute = zeitleiste_sam;} else {
if ((tag == 7) && ((woche == 0) || (woche == 3))) {zeitleiste_heute = zeitleiste_son;} else {
if ((tag >= 1) && (tag <= 5) && ((woche == 1) || (woche == 3))) {zeitleiste_heute = zeitleiste_mon;} else {
if ((tag >= 6) && (tag <= 7) && (woche == 1)) {zeitleiste_heute = zeitleiste_sam;} else {
if (woche == 2) {zeitleiste_heute = zeitleiste_mon;} }}}}}}}}}
! An Feiertagen gilt die Temperatur von Samstag bzw. Sonntag
if (dom.GetObject('Feiertag').State() && ((woche == 0) || (woche == 3))) {zeitleiste_heute = zeitleiste_son;} else {
if (dom.GetObject('Feiertag').State() && (woche == 1)) {zeitleiste_heute = zeitleiste_sam;}}
! Position der Zeitleiste bestimmen
if (system.Date("%M").ToInteger() > 29) {integer add = 1;} else {integer add = 0;}
integer sTime = (system.Date("%H").ToInteger()*2)+add;
heizwert = zeitleiste_heute.Substr(sTime, 1);
! Temperatur bestimmen, die gesetzt werden soll
if (heizwert == "0") {soll_neu = grad_0;} else {
if (heizwert == "1") {soll_neu = grad_1;} else {
if (heizwert == "2") {soll_neu = grad_2;} else {
if (heizwert == "3") {soll_neu = grad_3;} else {
if (heizwert == "4") {soll_neu = grad_4;} else {
if (heizwert == "5") {soll_neu = grad_5;} else {
if (heizwert == "6") {soll_neu = grad_6;} else {
if (heizwert == "7") {soll_neu = grad_7;} else {
if (heizwert == "8") {soll_neu = grad_8;} else {
if (heizwert == "9") {soll_neu = grad_9;} }}}}}}}}}
! letzte Solltemeratur bestimmen, dabei muß der wert von 00:00 beachtet werden - der letzte Wert war gestern
if (sTime == 0) {
if ((tag == 1) && ((woche == 0) || (woche == 3))) {zeitleiste_gestern = zeitleiste_son;} else {
if ((tag == 2) && (woche == 0)) {zeitleiste_gestern = zeitleiste_mon;} else {
if ((tag == 3) && (woche == 0)) {zeitleiste_gestern = zeitleiste_die;} else {
if ((tag == 4) && (woche == 0)) {zeitleiste_gestern = zeitleiste_mit;} else {
if ((tag == 5) && (woche == 0)) {zeitleiste_gestern = zeitleiste_don;} else {
if ((tag == 6) && (woche == 0)) {zeitleiste_gestern = zeitleiste_fre;} else {
if ((tag == 7) && ((woche == 0) || (woche == 3))) {zeitleiste_gestern = zeitleiste_sam;} else {
if ((tag >= 2) && (tag <= 6) && ((woche == 1) || (woche == 3))) {zeitleiste_gestern = zeitleiste_mon;} else {
if (((tag == 1) || (tag == 7)) && (woche == 1)) {zeitleiste_gestern = zeitleiste_sam;} else {
if (woche == 2) {zeitleiste_gestern = zeitleiste_mon;} }}}}}}}}}
heizwert = zeitleiste_gestern.Substr(47, 1);
} else {
heizwert = zeitleiste_heute.Substr((sTime-1), 1);
}
! Temperatur bestimmen, die in der letzten 30 Minutenn war
if (heizwert == "0") {soll_alt = grad_0;} else {
if (heizwert == "1") {soll_alt = grad_1;} else {
if (heizwert == "2") {soll_alt = grad_2;} else {
if (heizwert == "3") {soll_alt = grad_3;} else {
if (heizwert == "4") {soll_alt = grad_4;} else {
if (heizwert == "5") {soll_alt = grad_5;} else {
if (heizwert == "6") {soll_alt = grad_6;} else {
if (heizwert == "7") {soll_alt = grad_7;} else {
if (heizwert == "8") {soll_alt = grad_8;} else {
if (heizwert == "9") {soll_alt = grad_9;} }}}}}}}}}
} !Ende IF Anwesenheit
} !Ende IF Gaeste
} !Ende IF Urlaub
} !Ende IF Partytemperatur
} !Ende IF Fenster offen
} !Ende IF Heizungsperiode
if (soll_ist >= 0) { ! Wenn RT geantwortet hat (Sollwert konnte ausgelesen werden)...
! 4 % Bug check, Ist Temperatur muss größer als Fenster offentemperatur sein
if (ist_temp >= grad_fenster) {
if ((ist_temp >= soll_neu + grad_offs) && (ist_temp >= soll_ist + grad_offs)) {
if (stell_grad > 0) {
soll_neu = 0;
! gewährleistet, dass regler.State auf soll_neu gesetzt wird
soll_ist = 0.1;
prioritaet = true;
}
}
}
! ...dann prüfen ob neue Solltemperatur in RT geschrieben werden muss.
if (soll_ist <> soll_neu) { ! Wenn aktuelle Solltemperatur = neue Solltemp., dann nichts machen
time now = system.Date("%Y-%m-%d %H:%M:%S").ToTime(); ! wie spät ist es jetzt?
rt_timestamp = regler.Timestamp();
integer diff = now.ToInteger() - rt_timestamp.ToInteger();
if ((diff >= setdelta) || (prioritaet) || (soll_ist == grad_fenster) || (sv_timestamp >= rt_timestamp) || ((soll_ist == soll_alt) && (soll_alt <> soll_neu))) {
! Temperatur setzen
regler.State(soll_neu);
integer regler_gesetzt = 1;
if (debug) {
string stdout;
string stderr;
system.Exec("logger -t script -p user.debug Raumthermostat " # raum # " neu gesetzt!\n", &stdout, &stderr);
system.Exec("logger -t script -p user.debug alte_Solltemperatur: " # soll_ist # " neue_Solltemperatur: " # soll_neu # "\n", &stdout, &stderr);
system.Exec("logger -t script -p user.debug Fenster offen cnt: " # offen # " stellgrad akt:" # stell_grad # "%.\n", &stdout, &stderr);
system.Exec("logger -t script -p user.debug Letzte_Aenderung: " # rt_timestamp # " Zeitdifferenz:_" # diff # "sek.", &stdout, &stderr);
}
}
}
} else {
string stdout;
string stderr;
system.Exec("logger -t script -p user.debug Raumthermostat " # raum # " antwortet nicht!", &stdout, &stderr);
}