Steuert dynamisch meinen Mischermotor an der Heizung, kleinste Taktzeit ist 2 Sekunden, max Taktzeit 14 Sekunden, wird berechnet von der Temperaturdifferenz Sollwert - Istwert.
Hier mal das ganze Skript :
<?
///$Kp=1.5;//1.1; // 5 Kp = Verstärkungsfaktor Proportionalregler
$Ki=1; //2.5 Ki = Verstärkungsfaktor Integralregler
$Kd=1; //0 Kd = Verstärkungsfaktor Differenzialregler
$EinschaltzeitID = IPS_GetObjectIDByName("Einschaltzeit", ($_IPS['SELF']));
$WartezeitID = IPS_GetObjectIDByName("Wartezeit", ($_IPS['SELF']));
$actionID = IPS_GetObjectIDByName("Zustand", IPS_GetParent($_IPS['SELF']));
$VorherigeRegelabweichungID = IPS_GetObjectIDByName("Regelabweichung", IPS_GetParent($_IPS['SELF']));
$HystereseID = IPS_GetObjectIDByName("Hysterese", IPS_GetParent($_IPS['SELF']));
$MischerID = IPS_GetObjectIDByName("Mischer", IPS_GetParent($_IPS['SELF']));
$SteilheitID = IPS_GetObjectIDByName("Steilheit", IPS_GetParent($_IPS['SELF']));
$Korrektur_MischerID = IPS_GetObjectIDByName("Korrektur_Mischer", IPS_GetParent($_IPS['SELF']));
$PumpeID = IPS_GetObjectIDByName("Pumpe", IPS_GetParent($_IPS['SELF']));
$KpID = IPS_GetObjectIDByName("Verstärkungsfaktor Proportionalregler", IPS_GetParent($_IPS['SELF']));
$min_MischerID = IPS_GetObjectIDByName("Mischer Min", IPS_GetParent($_IPS['SELF']));
$max_MischerID = IPS_GetObjectIDByName("Mischer Max", IPS_GetParent($_IPS['SELF']));
$WartezeitVarID = IPS_GetObjectIDByName("Wartezeit", IPS_GetParent($_IPS['SELF']));
$id = IPS_GetParent($_IPS['SELF']);
$id2= IPS_GetParent($id);
$id3= IPS_GetObjectIDByName("Regler Aussentemperatur", $id2);
$HandID = IPS_GetObjectIDByName("Hand_Auto", $id3);
$UhrID = IPS_GetObjectIDByName("Uhr Heizung", $id3);
$Soll_TagID = IPS_GetObjectIDByName("Soll Tag", $id3);
$Soll_NachtID = IPS_GetObjectIDByName("Soll Nacht", $id3);
$IstTemperaturAussenID = IPS_GetObjectIDByName("Temperatur_Aussen", $id3);
$Aussentemp=GetValueFloat($IstTemperaturAussenID);
$Soll_Tag = GetValue($Soll_TagID);
$Soll_Nacht = GetValue($Soll_NachtID);
$Hand = GetValue($HandID);
$Uhr = GetValue($UhrID);
//var_dump ($Hand);
$Soll_Temperatur_MischerID = IPS_GetObjectIDByName("Soll_Temperatur_Mischer", IPS_GetParent($_IPS['SELF']));
$IstTemperaturID = IPS_GetObjectIDByName("Temperatur", IPS_GetParent($_IPS['SELF']));
$Hysterese =GetValueFloat($HystereseID);
$Steilheit = GetValue($SteilheitID);
$Korrektur_Mischer = GetValue($Korrektur_MischerID);
$Kp = GetValue($KpID);
$min_Mischer = GetValue($min_MischerID);
$max_Mischer = GetValue($max_MischerID);
$Wartezeit = GetValue($WartezeitVarID);
IPS_SetEventCyclic($WartezeitID, 0, 0, 0, 0, 1 ,$Wartezeit);
if ($Hand == 0) { //Automatik ist an
if ($Uhr == 1) {
$Raumsollwert= $Soll_Tag ;//12 Nacht
} else{
$Raumsollwert= $Soll_Nacht ;//12 Nacht
}
//Sommer, Pumpe aus, Kessel aus, Mischer zu
if ($Aussentemp < $Raumsollwert ) {
exec ('echo "0" > /sys/class/gpio/gpio23/value'); // Pumpe ein
$Vorlauftemperatur_Mischer=min(max(round((0.55*$Steilheit*(pow($Raumsollwert,($Aussentemp/(320-$Aussentemp*4))))*((-$Aussentemp+20)*2)+$Raumsollwert+$Korrektur_Mischer)*1)/1,$min_Mischer),$max_Mischer);
SetValueFloat($Soll_Temperatur_MischerID, $Vorlauftemperatur_Mischer);
} else{
// Ausentemp grösserr Raumsollwert
exec ('echo "1" > /sys/class/gpio/gpio23/value');// Pumpe aus
SetValueFloat($Soll_Temperatur_MischerID,$min_Mischer);//Wert anpassen !!!!!
}
}
$e = (GetValueFloat($Soll_Temperatur_MischerID)- GetValueFloat($IstTemperaturID));
// Die Berechnung des neuen Regelwertes
//$y = ($Kp * $e + $Ki * $Ta * $esum + $Kd * ($e - $ealt) / $Ta);
$y = $Kp * $e;
$Einschaltzeit=$y;
if ($Hand == 1) { //Hand ist an
$action = 'Hand';
}
SetValueFloat($VorherigeRegelabweichungID, $y);
$Einschaltzeit=abs($y);
IF ($Einschaltzeit <= 2) {
$Einschaltzeit = 2;
}
IF ($Einschaltzeit >= 14) {
$Einschaltzeit = 14;
}
IPS_SetEventCyclic($EinschaltzeitID, 0, 0, 0, 0, 1 ,$Einschaltzeit);
if (IPS_GetName($_IPS['EVENT'])=='Einschaltzeit') {
//Netzrelais aus
if ($Hand == 0) { //Automatik ist an
exec ('echo "1" > /sys/class/gpio/gpio17/value');
SetValueInteger($MischerID, 1); //Stop
}
IPS_SetEventActive($EinschaltzeitID,false);
IPS_SetEventActive($WartezeitID,true);
}
if (IPS_GetName($_IPS['EVENT'])=='Wartezeit') {
$Soll_VL = GetValue($Soll_Temperatur_MischerID);
$Ist_VL = GetValue($IstTemperaturID);
if ($Hand == 0) { //Automatik ist an
$action = 'Idle';
if ($Ist_VL < ($Soll_VL - $Hysterese) ) $action = 'Auf';
if ($Ist_VL > ($Soll_VL + $Hysterese) ) $action = 'Zu';
// if (GetValue(32015 /*[Objekt #32015 existiert nicht]*/) == False) $action = 'Idle';
Switch ($action){
Case 'Idle':
break;
Case 'Zu':
//Richtungsrelais aus
exec ('echo "1" > /sys/class/gpio/gpio27/value');
//Netzrelais ein
exec ('echo "0" > /sys/class/gpio/gpio17/value');
SetValueInteger($MischerID, 3); //Zu
break;
Case 'Auf':
//Richtungsrelais ein
exec ('echo "0" > /sys/class/gpio/gpio27/value');
//Netzrelais ein
exec ('echo "0" > /sys/class/gpio/gpio17/value');
SetValueInteger($MischerID, 0); //Auf
break;
}
}
SetValueString($actionID,$action);
IPS_SetEventActive($EinschaltzeitID,true);
IPS_SetEventActive($WartezeitID,false);
}
$x = intval(exec ('cat /sys/class/gpio/gpio23/value'));
if ($x == 1){ $x=0;} else { $x=1; }
SetValueBoolean($PumpeID,$x);
//}
?>