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 _SerSteps; public override Boolean IsControlledProgrammable(Profile profile) { foreach (Step step in profile.SerializedStepList) { List steps = new List(); steps.Add(step); Profile p = new Profile(_Client.Type.ToStr(), steps, new List(), 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 steps = new List(); steps.Add(_SerSteps[iStep].DeepClone()); // Loops List loops = new List(); // Options List options = new List(); // Create profile return new Profile(_Profile.Title, steps, loops, options); } } }