Files
newfolder/ChamChat/Client_PLxKPH/Task.PLxKPH.cs
Wesley Hofman 2f1f4199ad first commit
2025-09-18 14:23:18 +02:00

348 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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");
}
}
}