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

227 lines
8.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ChamChat.Models;
namespace ChamChat
{
public class HTS7057_Task : Task
{
// Each step is separately programmed to the TSE11.
// Steps are programmed at 110% of required step duration.
// End of program is always of shutdown type to avoid stressing to much. (Excluding last step)
// If next step is of different type (tA or tB), then the next temperature is prepared in other chamber.
// Default temperatures are 0 °C for tA and 85 °C for tB.
public HTS7057_Task(Client Client, Profile Profile)
: base(Client, Profile)
{
_Profile = Profile;
_Client = Client;
_SerSteps = _Profile.SerializedStepList;
}
// Needs to be overriden, because chamber is never stand alone programmable
public override Boolean IsStandAloneProgrammable(Profile profile)
{
return false;
}
private const Int32 PollingIntervalSeconds = 10;
private List<Step> _SerSteps;
public override Boolean IsControlledProgrammable(Profile profile)
{
foreach (Step step in profile.SerializedStepList)
{
List<Step> steps = new List<Step>();
steps.Add(step);
Profile p = new Profile(_Client.Type.ToStr(), steps, new List<Loop>(), profile.Options);
if (!_Client.IsProgrammable(p))
return false;
}
return true;
}
protected override void ThreadStandAlone()
{
_Status = TaskStatus.Aborted;
_TaskProgress = "Client cannot operate in standaline mode";
_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 += 1;
// Last step has been performed?
if (iCurrentSerialStep > _SerSteps.Count - 1)
{
// Do not stop client, but leave running if option given
if (_Profile.Options.Contains(ProfileOption.HTS7057_EndModeHold))
{
_Status = TaskStatus.Finished;
AddEventLog(ProfileOption.HTS7057_EndModeHold.ToStr());
_TaskProgress = ProfileOption.HTS7057_EndModeOff.ToStr();
_TaskProgress += string.Format(" (setting is {0:0.0} °C)", _SerSteps[_SerSteps.Count - 1].T);
continue;
}
else
{
_Client.Stop();
_Status = TaskStatus.Finished;
AddEventLog(ProfileOption.HTS7057_EndModeOff.ToStr());
_TaskProgress = ProfileOption.HTS7057_EndModeOff.ToStr();
continue;
}
}
Profile newProfile = GetProfile(iCurrentSerialStep);
currentStep = _SerSteps[iCurrentSerialStep];
AddEventLog(string.Format("{0} minutes @ {1:0.0} °C", _SerSteps[iCurrentSerialStep].DurationMin, _SerSteps[iCurrentSerialStep].T));
RestartClient(newProfile);
if (_Status != TaskStatus.IsRunning) // Might be altered in RestartClient()
continue;
// Update variables
startOfCurrentProgram = DateTime.Now;
endOfCurrentProgram = startOfCurrentProgram.AddMinutes(newProfile.DurationMin);
lastPolled = DateTime.Now;
}
// Poll only every 'PollingIntervalSeconds' seconds
if (DateTime.Now > lastPolled.AddSeconds(PollingIntervalSeconds))
{
// Is finished?
try
{
if (_Client.IsFinished())
{
_Status = TaskStatus.Interrupted; // Profile did not finish, client did
continue;
}
}
catch { }
try
{
double taskRunTimeMin = (DateTime.Now - _startThread).TotalMinutes;
double pTest = Math.Max(0,Math.Min(100, Math.Floor(taskRunTimeMin / _Profile.DurationMin * 100)));
double stepRuntime = (DateTime.Now - startOfCurrentProgram).TotalMinutes;
double pStep = Math.Max(0,Math.Min(100, Math.Floor(stepRuntime / _SerSteps[iCurrentSerialStep].DurationMin * 100)));
double taskTimeRemain = Math.Max(0, _Profile.DurationMin - taskRunTimeMin);
double taskTimeRemainHrs = Math.Floor(taskTimeRemain / 60);
double taskTimeRemainMin = Math.Floor(taskTimeRemain - 60 * taskTimeRemainHrs);
_TaskProgress = String.Format("Step #{0:00}/{1:00} progress {2:0}%, test progress {3:0}%, remaining test time {4:0}h{5:00}m", iCurrentSerialStep + 1, _Profile.SerializedStepList.Count, pStep, pTest, taskTimeRemainHrs, taskTimeRemainMin);
}
catch
{
_TaskProgress = "Progress could not be calculated.";
}
lastPolled = DateTime.Now;
}
System.Threading.Thread.Sleep(200);
if (_Status == TaskStatus.AbortRequested)
{
try
{
if (_Client.Stop())
_Status = TaskStatus.Aborted;
}
catch { }
}
_isKicking = true;
}
_isKicking = false;
}
private void RestartClient(Profile newProfile)
{
// Write profile
try
{
if (!_Client.WriteProfile(newProfile))
{
_Status = TaskStatus.Interrupted;
return;
}
}
catch (Exception ex)
{
_Status = TaskStatus.ExceptionOccured;
_TaskProgress = string.Format("Client WriteProfile() exception: {0}", ex.Message);
AddEventLog(_TaskProgress);
return;
}
// Start client
try
{
//AddEventLog("RestartClient.Start");
if (!_Client.Start())
{
_Status = TaskStatus.Interrupted;
return;
}
}
catch (Exception ex)
{
_Status = TaskStatus.ExceptionOccured;
_TaskProgress = string.Format("Client Start() exception: {0}", ex.Message);
AddEventLog(_TaskProgress);
return;
}
}
private Profile GetProfile(int iStep)
{
// Stepslist
List<Step> steps = new List<Step>();
steps.Add(_SerSteps[iStep].DeepClone());
// Loops
List<Loop> loops = new List<Loop>();
// Options
List<ProfileOption> options = new List<ProfileOption>();
// Create profile
return new Profile(_Profile.Title, steps, loops, options);
}
}
}