using System; using System.Collections.Generic; using System.Linq; using System.Text; using ChamChat.Models; namespace ChamChat { public partial class Watlow988U_Client : Client { // Defines private const Int32 _OptionRange = 5000; private const Int32 _DataTransferTimeOut = 1000; private const int _RAM = 1; private DateTime _ReadyToSend = DateTime.Now; // Timestamp when client is ready to communicate private DateTime _dtTestStart = DateTime.Now; public Watlow988U_Client(Int32 MIDS, ClientType Type) : base(MIDS, Type) { _InterfaceType = InterfaceType.FDTI_USB_COM485; // Set options available in client _Parameters = new List(); _Parameters.Add(Parameter.T); // Add option range _ClientOptions = new List(); foreach (ProfileOption o in Enum.GetValues(typeof(ProfileOption))) if ((int)o >= _OptionRange && (int)o < _OptionRange + 999) _ClientOptions.Add(o); // Set availabel addresses for programming _AvailableRAMs = new List(); for (int i = 1; i < 31; i++) _AvailableRAMs.Add(i); } // To do public override Profile ReadProfile(int RAM, ref System.ComponentModel.BackgroundWorker bgw) { string sAddr = _Address.ToString(); string cmd; string read; Profile profile = new Profile(); try { // Communicate with client cmd = sAddr + ",PRGMREAD,"; DataTransfer(cmd, out read, _DataTransferTimeOut); List steps = new List(); List loops = new List(); List options = new List(); String name = "Watlow988U_Client"; // Create profile profile = new Profile(name, steps, loops, options); } catch { } return profile; } // To do public override Boolean WriteProfile(Profile profile) { return true; } // To do public override Boolean WriteProfile(Profile profile, Int32 RAM) { return true; } // To do public override Boolean IsProgrammable(Profile profile) { // Profile is programmable if all below applies return true; } // To do public override Boolean HasAlarm(out List alarms) { alarms = new List(); return true; } // To do public override Boolean IsIdle() { // IsIdle() returns true if status of chamber is 'Standby'. See page 31 MODE?. string sAddr = _Address.ToString(); string cmd; string read; cmd = sAddr + ", MODE?"; DataTransfer(cmd, out read, _DataTransferTimeOut); if (read.Contains("STANDBY") || read.Contains("OFF")) return true; return false; } // To do public override Boolean Start() { if (_Profile == null) return false; string sAddr = _Address.ToString(); string cmd; string read; cmd = sAddr + ", MODE, RUN " + _RAM; // See page 47. DataTransfer(cmd, out read, _DataTransferTimeOut); _dtTestStart = DateTime.Now; return TxRxSucces(cmd, read); } // To do public override Boolean IsFinished() { // Finished() returns true if chamber is not running. See page 34 MODE?. string sAddr = _Address.ToString(); string cmd; string read; cmd = sAddr + ", MODE?"; DataTransfer(cmd, out read, _DataTransferTimeOut); if (read.Contains("OFF") || read.Contains("STANDBY")) return true; return false; } // To do public override Boolean Stop() { string sAddr = _Address.ToString(); string cmd; string read; cmd = sAddr + ", MODE, STANDBY"; // Pg. 47 DataTransfer(cmd, out read, _DataTransferTimeOut); return TxRxSucces(cmd, read); } // To do public override Boolean IsOnline() { try { string sAddr = _Address.ToString(); string cmd; string read; cmd = sAddr + ", ROM?"; // Pg. 27 DataTransfer(cmd, out read, _DataTransferTimeOut); return read.ToLower().Contains("jlc"); } catch { return false; } } // To do public override String Progress() { string sAddr = _Address.ToString(); string cmd; string read; //cmd = sAddr + ", MON?"; // See page 31 //DataTransfer(cmd, out read, _DataTransferTimeOut); //Double T = Double.Parse(read.Split(',')[0]); //Double RH = Double.Parse(read.Split(',')[1]); cmd = sAddr + ", PRGM MON?"; // See page 35 DataTransfer(cmd, out read, _DataTransferTimeOut); int step = Int32.Parse(read.Split(',')[1]) - 1; Double Tset = Double.Parse(read.Split(',')[2]); Double RHset = Double.Parse(read.Split(',')[3]); string time = read.Split(',')[4]; int hrs = Int32.Parse(time.Split(':')[0]); int min = Int32.Parse(time.Split(':')[1]); int cyclesLeft = Int32.Parse(read.Split(',')[5]); double stepTimeLeft = hrs * 60 + min; double stepDuration = _Profile.SerializedStepList[step].DurationMin; double stepRuntime = stepDuration - stepTimeLeft; double pStep = Math.Min(100, Math.Floor(stepRuntime / stepDuration * 100)); double testRunTime = (_dtTestStart - DateTime.Now).TotalMinutes; double pTest = Math.Min(100, Math.Floor(testRunTime / _Profile.DurationMin * 100)); double testTimeRemain = _Profile.DurationMin - testRunTime; double testTimeRemainHrs = Math.Floor(testTimeRemain / 60); double testTimeRemainMin = Math.Floor(testTimeRemain - 60 * testTimeRemainHrs); string progress = String.Format("Step #{0:00}/{1:00} progress {2:0}%, ", step + 1, _Profile.SerializedStepList.Count, pStep); progress += String.Format("remaining step time {0:0}h{1:00}m, remaining cycles {2:0}, ", hrs, min, cyclesLeft); progress += String.Format("test progress {0:0}%, remaining test time {1:0}h{2:00}m", pTest, testTimeRemainHrs, testTimeRemainMin); return progress; } // To do private bool TxRxSucces(string cmd, string read) { return true; #warning Implement TxRxSucces for Watlow988U // Command not correctly processed if (read.StartsWith("NA:")) return false; // No response received if (read.Trim().Length < 1) return false; // Handle monitoring commands if (cmd.Trim().Contains("?")) { return true; } else { if (read.Trim().StartsWith("OK:")) return true; } return false; } // NOT USED private string ANSItoASCII(string ansi) { string a; int i; // Remove all types spaces ansi = ansi.Replace(" ", "").Trim(); // Replace by char 5 a = ""; i = ansi.IndexOf(a); while (i > -1) { string sub = ansi.Substring(0, i); sub += (char)5; sub += ansi.Substring(i + a.Length); ansi = sub; i = ansi.IndexOf(a); } return ansi; } public Boolean StartCommLink() { string cmd = _Address.ToString(); cmd += (char)5; // Enquiry string read; DataTransferLog log = _Interface.DataTransfer(cmd, out read, 3000); log.Command = log.Command.Replace(((char)5).ToString(), ""); log.ReturnData = log.ReturnData.Replace(((char)6).ToString(), ""); AppendDataTransferLog(log); if (read.Contains(_Address.ToString()) && read.Contains((char)6)) { return true; } return false; } public void EndCommLink() { string cmd = ""; cmd += (char)16; // DataLink Escape string read; DataTransferLog log = _Interface.DataTransfer(cmd, out read, 0); // No response log.Command = log.Command.Replace(((char)16).ToString(), ""); AppendDataTransferLog(log); } // To do // Performs transfer and adds interface logs to list in Client parent class private Boolean DataTransfer(string cmd, out string read, int ReturnDataWaitms) { // If no maximum number of attempts is given, it defaults to 3. return DataTransfer(cmd, out read, ReturnDataWaitms, 3); } // To do // Performs transfer and adds interface logs to list in Client parent class private Boolean DataTransfer(string cmd, out string read, int ReturnDataWaitms, int MaxNumOfAttempts) { // Construct command to send cmd += (char)13; // CR cmd += (char)10; // LF cmd = cmd.Replace(" ", ""); // Wait for _ReadyToSend or max 1 seconds DateTime go = DateTime.Now.AddSeconds(1); while (DateTime.Now < _ReadyToSend && DateTime.Now < go) System.Threading.Thread.Sleep(10); read = ""; bool success = false; int attempts = 0; while (!success && attempts <= MaxNumOfAttempts) { DataTransferLog log = _Interface.DataTransfer(cmd, out read, ReturnDataWaitms); success = TxRxSucces(cmd, read); attempts++; // Mask for showing in GUI if (cmd.Contains("MODE?") || cmd.Contains("MON?")) log.ShowInGUI = false; // Notify user via GUI of failed attempts if (attempts > 1) log.Command += string.Format(" [Attempt {0:0}]", attempts); // Add to logs AppendDataTransferLog(log); // Set _ReadyToSend acc. manual specs if (cmd.Contains("IN1") || cmd.Contains("IN2") || cmd.Contains("CF")) _ReadyToSend = DateTime.Now.AddMilliseconds(2000); else _ReadyToSend = DateTime.Now.AddMilliseconds(1000); // Sleeps if (!success) System.Threading.Thread.Sleep(3000); // Sleep 3 seconds before resending if failed } return success; } } }