348 lines
13 KiB
C#
348 lines
13 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using ChamChat.Models;
|
||
|
||
namespace ChamChat
|
||
{
|
||
public class PLxKPH_Task : Task
|
||
{
|
||
public PLxKPH_Task(Client Client, Profile Profile)
|
||
: base(Client, Profile)
|
||
{
|
||
_Profile = Profile;
|
||
_Client = Client;
|
||
_SerSteps = _Profile.SerializedStepList;
|
||
}
|
||
|
||
private const Int32 PollingIntervalSeconds = 10;
|
||
|
||
private List<Step> _SerSteps;
|
||
|
||
|
||
public override Boolean IsControlledProgrammable(Profile profile)
|
||
{
|
||
ClientMessage msg = new ClientMessage(String.Format("The {0} can only operate in stand alone mode.", _Client.TypeDescription));
|
||
_Client.ClientMessages = new List<ClientMessage>();
|
||
_Client.ClientMessages.Add(msg);
|
||
return false;
|
||
}
|
||
|
||
|
||
protected override void ThreadStandAlone()
|
||
{
|
||
// Write profile
|
||
try
|
||
{
|
||
if (!_Client.WriteProfile(_Profile))
|
||
{
|
||
_Status = TaskStatus.Stopped;
|
||
return;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_Status = TaskStatus.ExceptionOccured;
|
||
_TaskProgress = string.Format("Client WriteProfile() exception: {0}", ex.Message);
|
||
return;
|
||
}
|
||
|
||
|
||
// Start client
|
||
try
|
||
{
|
||
if (!_Client.Start())
|
||
{
|
||
_Status = TaskStatus.Stopped;
|
||
return;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_Status = TaskStatus.ExceptionOccured;
|
||
_TaskProgress = string.Format("Client Start() exception: {0}", ex.Message);
|
||
return;
|
||
}
|
||
|
||
DateTime lastPolled = DateTime.Now;
|
||
|
||
while (_Status == TaskStatus.IsRunning)
|
||
{
|
||
// Poll only every 'PollingIntervalSeconds' seconds
|
||
if (DateTime.Now > lastPolled.AddSeconds(PollingIntervalSeconds))
|
||
{
|
||
// Is finished?
|
||
try
|
||
{
|
||
if (_Client.IsFinished())
|
||
{
|
||
_Status = TaskStatus.Finished;
|
||
continue;
|
||
}
|
||
}
|
||
catch { }
|
||
|
||
try
|
||
{
|
||
// Client return "Current conditions are x °C and x %rh"
|
||
_TaskProgress = _Client.Progress();
|
||
double runTimeMin = (DateTime.Now - StartOfTask).TotalMinutes;
|
||
double p = runTimeMin / _Profile.DurationMin * 100;
|
||
double remainTimeMin = Math.Max(0,_Profile.DurationMin - runTimeMin);
|
||
double hrs = Math.Floor(remainTimeMin /60);
|
||
double min = Math.Floor(remainTimeMin - 60 * hrs);
|
||
_TaskProgress += String.Format(", {0:0.0}% completed, {1:0}h{2:00} remaining",p, hrs,min );
|
||
|
||
}
|
||
catch { }
|
||
lastPolled = DateTime.Now;
|
||
}
|
||
|
||
System.Threading.Thread.Sleep(100);
|
||
|
||
if (_Status == TaskStatus.AbortRequested)
|
||
{
|
||
try
|
||
{
|
||
if (_Client.Stop())
|
||
_Status = TaskStatus.Aborted;
|
||
}
|
||
catch { }
|
||
}
|
||
|
||
_isKicking = true;
|
||
}
|
||
_isKicking = false;
|
||
}
|
||
|
||
|
||
|
||
|
||
protected override void ThreadControlled()
|
||
{
|
||
Int32 iCurrentSerialStep = -1;
|
||
DateTime startOfCurrentProgram = new DateTime(1900, 1, 1);
|
||
DateTime endOfCurrentProgram = new DateTime(1900, 1, 1);
|
||
Step currentStep = _SerSteps[0];
|
||
DateTime lastPolled = DateTime.Now;
|
||
|
||
while (_Status == TaskStatus.IsRunning)
|
||
{
|
||
if (DateTime.Now > endOfCurrentProgram)
|
||
{
|
||
iCurrentSerialStep++;
|
||
|
||
// Last step has been performed?
|
||
if (iCurrentSerialStep > _SerSteps.Count - 1)
|
||
{
|
||
_Client.Stop();
|
||
_Status = TaskStatus.Finished;
|
||
AddEventLog("Last step performed");
|
||
continue;
|
||
}
|
||
|
||
// Get step details
|
||
currentStep = _SerSteps[iCurrentSerialStep];
|
||
double TargetT = currentStep.T;
|
||
double TargetRH = currentStep.RH;
|
||
double DurationMin = currentStep.DurationMin;
|
||
|
||
double StartT = currentStep.T; // Set start to be target, but change to value of previous step if ramped.
|
||
if (currentStep.RampCtrlT)
|
||
{
|
||
if (iCurrentSerialStep == 0)
|
||
StartT = 23;
|
||
else
|
||
StartT = _SerSteps[iCurrentSerialStep - 1].T;
|
||
}
|
||
|
||
double StartRH = currentStep.RH; // Set start to be target, but change to value of previous step if ramped.
|
||
if (currentStep.RampCtrlRH)
|
||
{
|
||
if (iCurrentSerialStep == 0)
|
||
StartRH = 60;
|
||
else
|
||
StartRH = _SerSteps[iCurrentSerialStep - 1].RH;
|
||
}
|
||
|
||
RestartClient(DurationMin, StartT, TargetT, StartRH, TargetRH);
|
||
|
||
if (_Status != TaskStatus.IsRunning)
|
||
continue;
|
||
|
||
|
||
// Update variables
|
||
startOfCurrentProgram = DateTime.Now;
|
||
endOfCurrentProgram = DateTime.Now.AddMinutes(DurationMin);
|
||
lastPolled = DateTime.Now;
|
||
|
||
|
||
#region Update events
|
||
try
|
||
{
|
||
string s = "Set conditions: ";
|
||
if (currentStep.RampCtrlT)
|
||
s += String.Format("to {0:0.0} °C ({1:0.00} ˜°C/min), ", TargetT, (TargetT - StartT) / DurationMin);
|
||
else
|
||
s += String.Format("{0:0.0} °C, ", TargetT);
|
||
if (currentStep.RampCtrlRH)
|
||
s += String.Format("to {0:0.0} %rh ({1:0.00} ˜%rh/min), ", TargetRH, (TargetRH - StartRH) / DurationMin);
|
||
else
|
||
s += String.Format("{0:0.0} %rh, ", TargetRH);
|
||
|
||
s += string.Format("{0:0}h{1:00}", currentStep.Hours, currentStep.Minutes);
|
||
|
||
AddEventLog(s);
|
||
s = string.Format("Partial profile end is {0:00}-{1:00} @ {2:00}:{3:00}:{4:00}", endOfCurrentProgram.Day, endOfCurrentProgram.Month, endOfCurrentProgram.Hour, endOfCurrentProgram.Minute, endOfCurrentProgram.Second);
|
||
AddEventLog(s);
|
||
}
|
||
catch (Exception ex) { AddEventLog("Update events: " + ex.Message); }
|
||
#endregion Update events
|
||
}
|
||
|
||
|
||
|
||
// Poll only every 'PollingIntervalSeconds' seconds
|
||
if (DateTime.Now > lastPolled.AddSeconds(PollingIntervalSeconds))
|
||
{
|
||
// Is finished?
|
||
try
|
||
{
|
||
if (_Client.IsFinished())
|
||
{
|
||
// Last step is held (page 61) when program ends. Client will never finish by itself.
|
||
AddEventLog("Client finished, but task did not!");
|
||
_Status = TaskStatus.Interrupted; // Profile did not finish, client did
|
||
continue;
|
||
}
|
||
}
|
||
catch { } // Always continue and keep trying
|
||
|
||
|
||
#region Taskprogress
|
||
try
|
||
{
|
||
double taskRunTime = (DateTime.Now - _startThread).TotalMinutes;
|
||
double pTest = Math.Min(100, Math.Floor(taskRunTime / _Profile.DurationMin * 100));
|
||
double taskTimeRemain = _Profile.DurationMin - taskRunTime;
|
||
double taskTimeRemainHrs = Math.Floor(taskTimeRemain / 60);
|
||
double taskTimeRemainMin = Math.Floor(taskTimeRemain - 60 * taskTimeRemainHrs);
|
||
double currentStepRuntime = (DateTime.Now - startOfCurrentProgram).TotalMinutes;
|
||
double pStep = Math.Min(100, Math.Floor(currentStepRuntime / currentStep.DurationMin * 100));
|
||
_TaskProgress = String.Format("Step #{0:0}/{1:0} progress {2:0}%, test progress {3:0}%, remaining test time {4:0}h{5:00}m", iCurrentSerialStep + 1,_SerSteps.Count, pStep, pTest, taskTimeRemainHrs, taskTimeRemainMin);
|
||
if (iCurrentSerialStep + 1 == _SerSteps.Count && pTest > 99.99)
|
||
_TaskProgress = "Profile executed";
|
||
}
|
||
catch { _TaskProgress = "n/a"; }
|
||
#endregion Taskprogress
|
||
|
||
|
||
lastPolled = DateTime.Now;
|
||
}
|
||
|
||
System.Threading.Thread.Sleep(200);
|
||
|
||
_isKicking = true;
|
||
}
|
||
|
||
|
||
if (_Status == TaskStatus.AbortRequested)
|
||
{
|
||
try
|
||
{
|
||
if (_Client.Stop())
|
||
_Status = TaskStatus.Aborted;
|
||
}
|
||
catch { }
|
||
}
|
||
|
||
_isKicking = false;
|
||
}
|
||
|
||
|
||
private void RestartClient(Double DurationMin, Double StartT, Double TargetT, Double StartRH, Double TargetRH)
|
||
{
|
||
// Stop client
|
||
try
|
||
{
|
||
AddEventLog("Info: Stopping client");
|
||
if (!_Client.Stop())
|
||
{
|
||
_Status = TaskStatus.Interrupted;
|
||
AddEventLog("Task interrupted while trying to stop client!");
|
||
return;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_Status = TaskStatus.ExceptionOccured;
|
||
_TaskProgress = string.Format("Client Stop() exception: {0}", ex.Message);
|
||
AddEventLog(_TaskProgress);
|
||
return;
|
||
}
|
||
|
||
// Wait to finish
|
||
try
|
||
{
|
||
Boolean timedOut = true;
|
||
|
||
DateTime startWait = DateTime.Now;
|
||
while (DateTime.Now < startWait.AddSeconds(60))
|
||
{
|
||
System.Threading.Thread.Sleep(1000);
|
||
if (_Client.IsFinished())
|
||
{
|
||
timedOut = false;
|
||
break;
|
||
}
|
||
}
|
||
if (timedOut)
|
||
{
|
||
_Status = TaskStatus.Interrupted;
|
||
AddEventLog("Time out (60 s) in RestartClient.WaitForFinish");
|
||
return;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_Status = TaskStatus.ExceptionOccured;
|
||
_TaskProgress = string.Format("Client WaitForFinish exception: {0}", ex.Message);
|
||
AddEventLog(_TaskProgress);
|
||
return;
|
||
}
|
||
|
||
AddEventLog("Info: Client stopped");
|
||
|
||
|
||
// Start client
|
||
try
|
||
{
|
||
AddEventLog("Info: Starting client");
|
||
|
||
if (!((PLxKPH_Client)_Client).Start(DurationMin, StartT, TargetT, StartRH, TargetRH))
|
||
{
|
||
// Try to start again after 10 sec
|
||
AddEventLog("First attempt to start client failed!");
|
||
System.Threading.Thread.Sleep(10000);
|
||
|
||
if (!((PLxKPH_Client)_Client).Start(DurationMin, StartT, TargetT, StartRH, TargetRH))
|
||
{
|
||
_Status = TaskStatus.Interrupted;
|
||
AddEventLog("Task interrupted while trying to start client!");
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_Status = TaskStatus.ExceptionOccured;
|
||
_TaskProgress = string.Format("Client Start() exception: {0}", ex.Message);
|
||
AddEventLog(_TaskProgress);
|
||
return;
|
||
}
|
||
AddEventLog("Info: Client started");
|
||
}
|
||
}
|
||
}
|