using System; using System.Collections.Generic; using System.Linq; using System.Text; using ChamChat.Models; namespace ChamChat { public partial class HTS7057_Client : Client { private const Int32 _OptionRange = 4000; private const Int32 _DataTransferTimeOut = 1000; private DateTime _ReadyToSend = DateTime.Now; // Timestamp when client is ready to communicate private DateTime _dtTestStart = DateTime.Now; public HTS7057_Client(Int32 MIDS, ClientType Type) : base(MIDS, Type) { // Set options available in client _Parameters = new List(); _Parameters.Add(Parameter.T); //_Parameters.Add(Parameter.RampT); // 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); _InterfaceType = InterfaceType.FDTI_USB_COM422; } public override Profile ReadProfile(int RAM, ref System.ComponentModel.BackgroundWorker bgw) { String title = string.Format("{0:00000} {1}", _MIDS, _Type.ToStr()); List steps = new List(); Step step = new Step(365 * 24 * 60); string cmd; string read; cmd = string.Format("${0:00}I", _Address); DataTransfer(cmd, out read, _DataTransferTimeOut); if (read.Length >= 6) { double sw = 0; if (double.TryParse(read.Substring(0, 6), out sw)) { step.T = sw; } } steps.Add(step); return new Profile(title, steps, new List(), new List()); } public override Boolean WriteProfile(Profile profile) { return WriteProfile(profile, -1); } public override Boolean WriteProfile(Profile profile, int RAM) { // Only stand alone profiles allowed! if (!IsProgrammable(profile)) return false; _Profile = profile; return true; } public override Boolean IsProgrammable(Profile profile) { // Profile is programmable if all below applies // Profile contains just 1 step if (profile.SerializedStepList.Count != 1) { _ClientMessages.Add(new ClientMessage("Temperature range is -70 to 200 °C")); return false; } Step step = profile.SerializedStepList[0]; // Temperature is limited between -70 & 200 °C if (step.T < -70 || step.T > 200) { _ClientMessages.Add(new ClientMessage("Temperature range is -70 to 200 °C")); return false; } return true; } // To do public override Boolean HasAlarm(out List alarms) { alarms = new List(); return true; } public override Boolean IsIdle() { // Chamber is idle if return value's last 16 chars are 0 string cmd; string read; cmd = string.Format("${0:00}I", _Address); DataTransfer(cmd, out read, _DataTransferTimeOut); try { if (read.Substring(15,1) == "0") return true; } catch { } return false; } public override Boolean Start() { // Command consists of $01E xXxx.x bbbbbbbb // The minus sign for temperature must be on location of X // Bit 3 is on/off bit of chamber (return as bit 1 in 16-bit output) // Bit 5 is on/off bit of heater/cooler (return as bit 3 in 16-bit output) if (_Profile == null) return false; string cmd; string read; double t = _Profile.Steps[0].T; if( t< 0) cmd = string.Format("${0:00}E 0-{1:00.0} 00010100", _Address, Math.Abs(t)); else cmd = string.Format("${0:00}E {1:0000.0} 00010100", _Address, t); DataTransfer(cmd, out read, _DataTransferTimeOut); _dtTestStart = DateTime.Now; return TxRxSucces(cmd, read); } public override Boolean IsFinished() { // Chambers does not finish on its own return IsIdle(); } public override Boolean Stop() { string cmd; string read; cmd = string.Format("${0:00}E 0023.0 00000000", _Address); DataTransfer(cmd, out read, _DataTransferTimeOut); return TxRxSucces(cmd, read); } public override Boolean IsOnline() { // Chamber is online if Sollwert in °C is returned string cmd; string read; cmd = string.Format("${0:00}I", _Address); DataTransfer(cmd, out read, _DataTransferTimeOut); if (read.Length < 6) return false; double sw = 0; if (double.TryParse(read.Substring(0, 6), out sw)) return true; return false; } public override String Progress() { string cmd; string read; cmd = string.Format("${0:00}I", _Address); DataTransfer(cmd, out read, _DataTransferTimeOut); if (read.Length < 13) return "n/a"; string progress = ""; double sw = 0; if (double.TryParse(read.Substring(0, 6), out sw)) progress += string.Format("Setting is {0:0.0} °C", sw); double iw = 0; if (double.TryParse(read.Substring(7, 6), out iw)) progress += string.Format(", current temperature is {0:0.0} °C",iw); if (progress.Length == 0) progress += "n/a"; return progress; } private bool TxRxSucces(string cmd, string read) { if (cmd.Contains("I")) if (read.Length == 30) if (read.Substring(4, 1) == "." && read.Substring(11, 1) == ".") return true; if (cmd.Contains("E")) return read == "0"; return false; } // 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); } // 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 = 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(50); 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("I")) 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 _ReadyToSend = DateTime.Now.AddMilliseconds(2000); // Sleeps if (!success) System.Threading.Thread.Sleep(3000); // Sleep 3 seconds before resending if failed } return success; } } }