Tänkte göra en liten statusuppdatering. Nu har jag kommit ytterligare en bit på vägen i mitt projekt att styra värmen i huset. Det nya ställdonet är på plats och det styrs nu av ett program som körs på en annan server än den som syns på bilden. Tänkte lyfta över programmet till servern på bilden när jag ser att allt fungerar.
Klistrar in programmet i sin helhet här, ifall någon är intresserad.
- Kod: Markera allt
<?php
// Debug?
define("DEBUG", true);
// Declare variables
$DeltaTime = 10;
$Continue = true;
$OutdoorTemp = 2;
// Quit nicely when asked to
function SignalHandler($signal)
{
switch ($signal) {
case SIGTERM:
case SIGINT:
$Continue = false;
break;
}
}
// Linear interpolation between two known points
function Interpolate($x0, $y0, $x1, $y1, $x)
{
if ($x == $x0)
return $y0;
if ($x == $x1)
return $y1;
else
return $y0+($x-$x0)*($y1-$y0)/($x1-$x0);
}
// Sets the valve position between 0 and 100 %
function SetValvePosition($position)
{
$Temp = Interpolate(0, 255, 100, 0, $position);
$Output = round(min(max(intval($Temp), 0), 255));
exec("owwrite -s 192.168.1.2 /shunt/wiper $Output");
echo "Wrote $Output to wiper\n";
}
function PIDController($setpoint, $actual_value)
{
$PGain = 1.0;
$IGain = 0.1;
$DGain = 10.0;
global $DeltaTime;
static $PreviousError = 0;
static $IntegralPart = 0;
// Calculate deviation
$Error = $setpoint - $actual_value;
// Proportional part
$Proportional = $PGain * $Error;
// Integral part
$IntegralPart = $IntegralPart + $Error * $DeltaTime;
$Integral = min(max($IGain * $IntegralPart, -100), 100);
// Derivative part
$Derivative = $DGain * ($Error - $PreviousError)/$DeltaTime;
// Combine P, I and D
$Output = $Proportional + $Integral + $Derivative;
// Limit output
$Output = min(max($Output, 0), 100);
if (DEBUG) echo "Regulator output: ".round($Output, 1)." %\n";
if (DEBUG) echo "P: ".round($Proportional, 1);
if (DEBUG) echo " I: ".round($Integral, 1);
if (DEBUG) echo " D: ".round($Derivative, 1)."\n";
// Update error
$PreviousError = $Error;
return $Output;
}
// Setup signal handler
pcntl_signal(SIGTERM, "SignalHandler");
// Main loop
while ($Continue)
{
// Get supply temp
$SupplyTemp = floatval(exec("owread -s 192.168.1.2 /uncached/framledning_rad/temperature"));
if (DEBUG) echo "Supply temperature: $SupplyTemp C\n";
// Get outdoor temp
// implement later
// Calculate setpoint
$Setpoint = Interpolate(-20, 50, 20, 20, $OutdoorTemp);
if (DEBUG) echo "Setpoint: $Setpoint C\n";
// Call PID regulator
$PIDOutput = PIDController($Setpoint, $SupplyTemp);
// Set the valve position
SetValvePosition($PIDOutput);
// Wait a while
sleep($DeltaTime);
}
?>
Edit:
Kan tillägga att jag "tänkt" göra en mer fast installation, får se hur det blir med det.
Här kan ni se framledningstemperaturen i en graf:
http://solhaga.homeip.net/?page_id=101Sidan är under uppbyggnad, så ha överseende med eventuella konstigheter...
Regleringen har varit stabil med avvikelser < 0,2 °C i nån timma nu, så det ser ut att fungera.