first commit

This commit is contained in:
Wesley Hofman
2025-09-18 14:23:18 +02:00
commit 2f1f4199ad
293 changed files with 54467 additions and 0 deletions

161
ChamChat/Models/ANSIX328.cs Normal file
View File

@@ -0,0 +1,161 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public static class ANSI_X328
{
private static List<AA_Pare> _AA_Pares = new List<AA_Pare>()
{
new AA_Pare("<STX>",2),
new AA_Pare("<ETX>",3),
new AA_Pare("<EOT>",4),
new AA_Pare("<ENQ>",5),
new AA_Pare("<ACK>",6),
new AA_Pare("<LF>",10),
new AA_Pare("<CR>",13),
new AA_Pare("<DLE>",16),
new AA_Pare("<NAK>",21),
new AA_Pare("<XON>",17),
new AA_Pare("<XOFF>",19),
new AA_Pare("<SP>",32),
new AA_Pare("<SPACE>",32)
};
public static string ToStringOfHexPerChar(String ANSIX328, bool Separate)
{
byte[] asciiBytes = Encoding.ASCII.GetBytes(ANSIX328);
string result = "";
foreach (byte b in asciiBytes)
{
result += b.ToHex();
if (Separate)
result += " ";
}
return result.Trim();
}
public static String ToASCII(String ANSIX328)
{
// Remove all space.
// Find Ansi code, break string at Ansi, add ascii char and reattach rest of string
String result = ANSIX328.Replace(" ", "");
foreach (AA_Pare p in _AA_Pares)
{
while (result.Contains(p.Ansi))
{
int i = result.IndexOf(p.Ansi);
string pre = result.Substring(0, i);
string post = result.Substring(i + p.Ansi.Length);
result = pre + (char)p.Ascii + post;
}
}
return result;
}
public static String ToANSI(String ASCII)
{
String result = ASCII;
foreach (AA_Pare p in _AA_Pares)
{
for (int c = 0; c < result.Length; c++)
{
if (result.ToCharArray()[c] == (char)p.Ascii)
{
string pre = result.Substring(0, c);
string post = result.Substring(c + 1);
result = pre + p.Ansi + post;
c = -1;
// Test to show ASCII as decimal
//result = pre + "<"+p.Ascii.ToString()+">" + post;
}
}
}
return result;
}
internal class AA_Pare
{
public AA_Pare(String Ansi, Int32 Ascii)
{
_Ansi = Ansi;
_Ascii = Ascii;
}
private int _Ascii; public Int32 Ascii { get { return _Ascii; } }
private string _Ansi; public String Ansi { get { return _Ansi; } }
}
// Old implementations, not in use anymore
private static string[] _Ansi = new string[13] { "<ENQ>", "<ACK>", "<DLE>", "<STX>", "<NAK>", "<EOT>", "<ETX>", "<CR>", "<LF>", "<SP>", "<XOFF>", "<XON>", "<SPACE>" };
private static int[] _Ascii = new int[13] { 5, 6, 16, 2, 21, 4, 3, 13, 10, 32, 19, 17, 32 };
public static String ToANSI(String ASCII, bool old)
{
String result = ASCII;
for (int k = 0; k < _Ascii.Length; k++)
{
for (int c = 0; c < result.Length; c++)
{
if (result.ToCharArray()[c] == (char)_Ascii[k])
{
string pre = result.Substring(0, c);
string post = result.Substring(c + 1);
result = pre + _Ansi[k] + post;
// Test to show ASCII as decimal
//result = pre + "<"+_Ascii[k].ToString()+">" + post;
c = -1;
}
}
}
return result;
}
public static String ToASCII(String ANSIX328, bool old)
{
// Remove all space, etc.
// Find Ansi code, break string at Ansi, add ascii char and reattach rest of string
String result = ANSIX328.Replace(" ", "");
for (int k = 0; k < _Ansi.Length; k++)
{
String Ansi = _Ansi[k];
while (result.Contains(Ansi))
{
int i = result.IndexOf(Ansi);
string pre = result.Substring(0, i);
string post = result.Substring(i + Ansi.Length);
result = pre + (char)_Ascii[k] + post;
}
}
return result;
}
}
}

12
ChamChat/Models/Alarm.cs Normal file
View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public class Alarm
{
}
}

148
ChamChat/Models/Client.cs Normal file
View File

@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ChamChat.Models;
namespace ChamChat
{
public abstract class Client
{
public Client(Int32 MIDS, ClientType Type)
{
_MIDS = MIDS;
_Type = Type;
_DataTransferLogs = new List<DataTransferLog>();
}
protected Int32 _MIDS = 0; public Int32 MIDS { get { return _MIDS; } set { _MIDS = value; } }
protected Int32 _Address = 1; public Int32 Address { get { return _Address; } set { _Address = value; } }
protected Interface _Interface; public Interface Interface { get { return _Interface; } set { _Interface = value; } }
protected InterfaceType _InterfaceType;
public InterfaceType InterfaceType { get { return _InterfaceType; } } // Interface type is set as constant
protected List<ProfileOption> _ClientOptions; public List<ProfileOption> Options { get { return _ClientOptions; } }
protected List<Parameter> _Parameters; public List<Parameter> Parameters { get { return _Parameters; } }
protected String _InterfaceID; public String InterfaceID { get { return _Interface.ID; } }
protected Profile _Profile;
protected List<Alarm> _Alarms; public List<Alarm> Alarms { get { return _Alarms; } }
protected List<Int32> _AvailableRAMs = new List<int>(); public List<Int32> AvailableRAMs { get { return _AvailableRAMs; } }
protected ClientType _Type; public ClientType Type { get { return _Type; } }
protected string _DataTransferLogFile = null; // Set in Task.InitDataTransferLog()
public String DataTransferLogFile { get { return _DataTransferLogFile; } set { _DataTransferLogFile = value; } }
protected List<ClientMessage> _ClientMessages = new List<ClientMessage>(); public List<ClientMessage> ClientMessages { get { return _ClientMessages; } set { _ClientMessages = value; } }
public String TypeDescription { get { return _Type.ToStr(); } }
protected void AppendDataTransferLog(DataTransferLog log)
{
try
{
// Save all logs to file, but only keep the logs to show in the GUI in memory.
if (log.ShowInGUI)
this._DataTransferLogs.Add(log);
if (_DataTransferLogFile != null)
{
using (StreamWriter sw = File.AppendText(_DataTransferLogFile))
{
sw.WriteLine(log.ToCSV());
}
}
}
catch { }
}
protected List<DataTransferLog> _DataTransferLogs;
public List<DataTransferLog> DataTransferLogs
{
get
{
List<DataTransferLog> result = new List<DataTransferLog>();
int n = _DataTransferLogs.Count;
for (int i = 0; i < n; i++)
{
result.Add(_DataTransferLogs[i]);
}
return result;
}
set { _DataTransferLogs = value; } // Is set to new list in Task constructor
}
public abstract Profile ReadProfile(int RAM, ref System.ComponentModel.BackgroundWorker bgw);
public abstract Boolean WriteProfile(Profile Profile);
public abstract Boolean WriteProfile(Profile Profile, int RAM);
public abstract Boolean WriteProfile(Profile Profile, int RAM, ref System.ComponentModel.BackgroundWorker bgw);
public abstract Boolean Start();
public abstract Boolean Stop();
public abstract Boolean IsFinished();
public abstract Boolean HasAlarm(out List<Alarm> _Alarms);
/// <summary>
/// Checks if the given profile can run stand alone or if connection is required during running
/// </summary>
public abstract Boolean IsProgrammable(Profile profile);
/// <summary>
/// Checks if the client is executing a profile
/// </summary>
public abstract Boolean IsIdle();
/// <summary>
/// Checks the connection by sending and receiving a simple command
/// </summary>
public abstract Boolean IsOnline();
/// <summary>
/// Checks if given option is available for programming in this client
/// </summary>
public Boolean IsAvailable(ProfileOption Option)
{
return _ClientOptions.Contains(Option);
}
public override string ToString() { return string.Format("{0:00000} {1}", _MIDS, _Type.ToStr()); }
/// <summary>
/// Gives a string containing info on progress
/// </summary>
public abstract String Progress();
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public class ClientMessage
{
private string _Message = ""; public String Message { get { return _Message; } }
private DateTime _TimeStamp = DateTime.Now; public DateTime TimeStamp { get { return _TimeStamp; } }
public ClientMessage(string Message)
{
_Message = Message;
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public enum ClientType
{
// TSx
TSD100,
TSD100S,
TSE11A,
// LHL113
LHL113,
// HTS7057
HTS7057,
// PLxKPH
PL2KPH,
PL3KPH,
// Despatch
Despatch_Watlow988U
}
public static class ClientTypeExtensions
{
public static string ToStr(this ClientType Type)
{
switch (Type)
{
case ClientType.TSD100:
return "TSD100";
case ClientType.TSD100S:
return "TSD100 (300 °C)";
case ClientType.TSE11A:
return "TSE11A";
case ClientType.LHL113:
return "LHL113";
case ClientType.HTS7057:
return "HT/S 7057";
case ClientType.PL2KPH:
return "PL2-KPH";
case ClientType.PL3KPH:
return "PL3-KPH";
case ClientType.Despatch_Watlow988U:
return "Despatch";
default:
return Type.ToString();
}
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public class DataTransferLog
{
public DataTransferLog(String Command, String ReturnData, Interface IF)
{
_Command = Command.Trim();
_ReturnData = ReturnData.Trim();
_Interface = IF;
_Timestamp = DateTime.Now;
}
private Boolean _ShowInGUI = true; public Boolean ShowInGUI { get { return _ShowInGUI; } set { _ShowInGUI = value; } }
private string _Command; public String Command { get { return _Command; } set { _Command = value; } }
private string _ReturnData; public String ReturnData { get { return _ReturnData; } set { _ReturnData = value; } }
private Interface _Interface; public Interface InterfaceID { get { return _Interface; } }
private DateTime _Timestamp; public DateTime Timestamp { get { return _Timestamp; } }
public override string ToString()
{
DateTime d = _Timestamp;
string sTimestamp = String.Format("{0:0000}-{1:00}-{2:00} @ {3:00}:{4:00}:{5:00}.{6:000}", d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second, d.Millisecond);
return String.Format("{0} : Tx '{1}', Rx '{2}'", sTimestamp, _Command, _ReturnData).Trim().Replace(Environment.NewLine, "");
}
public string ToCSV()
{
DateTime d = _Timestamp;
//string sTimestamp = String.Format("{0:0000}-{1:00}-{2:00} @ {3:00}:{4:00}:{5:00}.{6:000}", d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second, d.Millisecond);
string sTimestamp = String.Format("{1:00}-{2:00} @ {3:00}:{4:00}:{5:00}.{6:000}", d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second, d.Millisecond);
return String.Format("{0}; {1}; {2}", sTimestamp, _Command, _ReturnData).Trim().Replace(Environment.NewLine,"");
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public static class ExtensionMethods
{
public static String GetTags(this String XML, String Tag)
{
try
{
int i1 = XML.IndexOf("<" + Tag + ">") + Tag.Length + 2;
int i2 = XML.IndexOf("</" + Tag + ">");
return XML.Substring(i1, i2 - i1);
}
catch
{
return "";
}
}
public static String ToHex(this byte Dec)
{
return Dec.ToString("X").PadLeft(2,'0');
}
//public static Int32[] HrsMinSecFromMinutes(this double Minutes)
//{
// int[] result = new int[3];
// int hrs = (int)Math.Floor(Minutes / 60);
// double left = Minutes - 60 * (double)hrs;
// int min = (int)Math.Floor(left / 60);
// left -= (double)min;
// int sec = (int)Math.Floor(left * 60);
// return result;
//}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public enum FlowControl
{
FT_FLOW_NONE = 0,
FT_FLOW_RTS_CTS = 256,
FT_FLOW_DTR_DSR = 512,
FT_FLOW_XON_XOFF = 1024
}
}

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ChamChat.Models;
namespace ChamChat
{
public enum InterfaceType
{
Undefined,
FDTI_USB_COM422,
FDTI_USB_COM485,
FDTI_USB_RS232,
}
public abstract class Interface
{
public Interface()
{
_ID = null;
}
public Interface(String ID )
{
_ID = ID;
}
protected string _ID = null; public String ID { get { return _ID; }}
protected InterfaceType _Type = InterfaceType.Undefined; public InterfaceType Type { get { return _Type; } }
protected InterfaceStatus _InterfaceStatus; public InterfaceStatus InterfaceStatus { get { return _InterfaceStatus; } }
/// <summary>
/// Datatransfer sends to and reads from interface.
/// </summary>
/// <param name="Command">Command to send</param>
/// <param name="Data">Data read from client</param>
/// <param name="ReturnDataWaitms">Client dependent wait time in ms after sending command prior to reading reply</param>
public abstract DataTransferLog DataTransfer(String Command, out String Data, Int32 ReturnDataWaitms);
/// <summary>
/// Open static connection to the interface
/// </summary>
abstract public Boolean Open();
/// <summary>
/// Close connection to the interface
/// </summary>
abstract public Boolean Close();
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat
{
public class InterfaceStatus
{
public InterfaceStatus(String Message)
{
_Message = Message;
}
public InterfaceStatus(String Message, String Status)
{
_Message = Message;
_Status = Status;
}
private string _Message; public String Message { get { return _Message; } }
private string _Status; public String Status { get { return _Status; } }
public override string ToString()
{
return "InterfaceStatus: " + _Message + " | " + _Status;
}
}
}

121
ChamChat/Models/Loop.cs Normal file
View File

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public class Loop
{
/// <summary>
/// Loop
/// </summary>
/// <param name="N">Number of times to perform the steps in the loop</param>
/// <param name="First">First step in loop (index in Profile.Steps)</param>
/// <param name="Last">Last step in loop (index in Profile.Steps)</param>
public Loop(Int32 N, Int32 First, Int32 Last)
{
_N = N;
_First = First;
_Last = Last;
}
private Int32 _N = 0; public Int32 N { get { return _N; } set { _N = value; } }
private Int32 _First = 0; public Int32 First { get { return _First; } set { _First = value; } }
private Int32 _Last = 0; public Int32 Last { get { return _Last; } set { _Last = value; } }
public Boolean Equals(Loop l)
{
return l.ToString() == this.ToString();
}
public override string ToString()
{
String s = string.Format("{2}x[s{0}..s{1}]", _First, _Last, _N);
return s;
}
public Loop(String XML)
{
string fp = "<" + this.GetType().Namespace + "." + this.GetType().Name + ">";
if (!XML.Contains(fp))
throw new Exception(fp + " tag not found!");
try
{
_N = Int32.Parse(XML.GetTags("_N"));
_First = Int32.Parse(XML.GetTags("_First"));
_Last = Int32.Parse(XML.GetTags("_Last"));
}
catch
{
throw new Exception(fp +": could not create instance from input string!");
}
}
public String XML
{
get
{
string xml = "";
xml += "<"+this.GetType().Namespace + "." + this.GetType().Name + ">";
xml += String.Format("<_N>{0:0}</_N>", _N);
xml += String.Format("<_First>{0:0}</_First>", _First);
xml += String.Format("<_Last>{0:0}</_Last>", _Last);
xml += "</" + this.GetType().Namespace + "." + this.GetType().Name + ">";
return xml;
}
}
}
public static class ExtensionsToLoop
{
public static List<Loop> OrderByLastAsc(this List<Loop> list)
{
List<Loop> result = new List<Loop>();
List<Loop> copy = new List<Loop>();
if (list == null)
return result;
if (list.Count < 2)
return list;
foreach (Loop l in list)
copy.Add(l);
while (copy.Count > 0)
{
Loop lowest = copy[0];
foreach (Loop l in copy)
{
if (l.Last == lowest.Last)
if (l.First > lowest.First)
lowest = l;
if (l.Last < lowest.Last)
lowest = l;
}
result.Add(lowest);
copy.Remove(lowest);
}
return result;
}
}
}

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{09375A4A-28B8-427B-853D-75C03A070728}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ChamChat.Models</RootNamespace>
<AssemblyName>ChamChat.Models</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Alarm.cs" />
<Compile Include="ANSIX328.cs" />
<Compile Include="Client.cs" />
<Compile Include="ClientMessage.cs" />
<Compile Include="ClientTypes.cs" />
<Compile Include="DataTransferLog.cs" />
<Compile Include="ExtensionMethods.cs" />
<Compile Include="FlowControl.cs" />
<Compile Include="Interface.cs" />
<Compile Include="InterfaceStatus.cs" />
<Compile Include="Loop.cs" />
<Compile Include="Profile.cs" />
<Compile Include="ProflileOptions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Step.cs" />
<Compile Include="Task.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

216
ChamChat/Models/Profile.cs Normal file
View File

@@ -0,0 +1,216 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public class Profile
{
public Profile(String Title, List<Step> Steps, List<Loop> Loops, List<ProfileOption> Options)
{
_Title = Title;
_Steps = Steps;
_Loops = Loops;
_Options = Options;
for (int i = 0; i < _Steps.Count; i++)
_Steps[i].PK = i;
}
public Profile() { }
private String _Title = "<NAME>"; public String Title { get { return _Title; } set { _Title = value; } }
private List<Step> _Steps = new List<Step>(); public List<Step> Steps { get { return _Steps; } } // No way to set steps due to PK setting in constructor
private List<Loop> _Loops = new List<Loop>(); public List<Loop> Loops { get { return _Loops; } }
private List<ProfileOption> _Options = new List<ProfileOption>(); public List<ProfileOption> Options { get { return _Options; } set { _Options = value; } }
private Int32 _ClientMIDS = 0; public Int32 ClientMIDS { get { return _ClientMIDS; } set { _ClientMIDS = value; } }
public Double DurationMin
{
get
{
double min = 0;
foreach (Step step in SerializedStepList)
min += step.DurationMin;
return min;
}
}
public Int32 Hours { get { return (int)Math.Floor(DurationMin / 60); } }
public Int32 Minutes { get { return (int)Math.Round(DurationMin - 60 * Hours); } }
public Double MaximumTemperature
{
get
{
double max = double.MinValue;
foreach (Step step in _Steps)
{
max = Math.Max(step.T, max);
max = Math.Max(step.PreTemp, max);
max = Math.Max(step.LimitT, max);
}
return max;
}
}
public List<Step> SerializedStepList
{
get
{
List<Step> result = new List<Step>();
foreach (Step step in _Steps)
result.Add(step);
// Order loops with asc Last
List<Loop> loops = _Loops.OrderByLastAsc();
// Insert loops
foreach (Loop loop in loops)
{
// Find first index in step list of loop.first
int f = result.FindIndex(delegate(Step p) { return (p.PK == loop.First); });
int l = result.FindIndex(delegate(Step p) { return (p.PK == loop.Last); });
List<Step> sub = new List<Step>();
for (int n = 0; n < loop.N - 1; n++)
{
for (int i = f; i <= l; i++)
{
Step s = result[i].DeepClone();
s.PK = -99;
sub.Add(s);
}
}
int q = l - f + 1; // Insert sub after original
result.InsertRange(f + q, sub);
}
return result;
}
}
public Profile(String XML)
{
string fp = "<" + this.GetType().Namespace + "." + this.GetType().Name + ">";
if (!XML.Contains(fp))
throw new Exception(fp + " tag not found!");
try
{
// Title
_Title = XML.GetTags("_Title");
// Options
_Options = new List<ProfileOption>();
string[] sOptions = XML.GetTags("_Options").Split(',');
int o = 0;
foreach (string s in sOptions)
if (Int32.TryParse(s, out o))
_Options.Add((ProfileOption)o);
// Loops
_Loops = new List<Loop>();
for (int i = 0; i < 100000; i++)
{
string loop = XML.GetTags(String.Format("Loop{0:000}", i));
if (loop == "")
break;
else
_Loops.Add(new Loop(loop));
}
// Steps
_Steps = new List<Step>();
for (int i = 0; i < 100000; i++)
{
string step = XML.GetTags(String.Format("Step{0:000}", i));
if (step == "")
break;
else
_Steps.Add(new Step(step));
}
// Client
Int32.TryParse(XML.GetTags("_ClientMIDS"), out _ClientMIDS);
}
catch
{
throw new Exception(fp + ": could not create instance from input string!");
}
}
public String XML
{
get
{
string xml = "<" + this.GetType().Namespace + "." + this.GetType().Name + ">";
xml += "<_Title>" + _Title + "</_Title>";
for (int i = 0; i < _Steps.Count; i++)
xml += String.Format("<Step{0:000}>{1}</Step{0:000}>", i, _Steps[i].XML);
for (int i = 0; i < _Loops.Count; i++)
xml += String.Format("<Loop{0:000}>{1}</Loop{0:000}>", i, _Loops[i].XML);
string o = "";
foreach (ProfileOption option in _Options)
o += ((int)option).ToString() + ",";
if (o.EndsWith(","))
o = o.Substring(0, o.Length - 1);
xml += "<_Options>" + o + "</_Options>";
xml += "<_ClientMIDS>" + _ClientMIDS.ToString() + "</_ClientMIDS>";
xml += "</" + this.GetType().Namespace + "." + this.GetType().Name + ">";
return xml;
}
}
public override string ToString()
{
string s = string.Format("{0:0} steps,", _Steps.Count);
s += string.Format("{0:0} serial steps,", SerializedStepList.Count);
if (_Loops.Count == 0)
s += "no loops, ";
else
foreach (Loop l in _Loops)
s += l.ToString() + ", ";
s += String.Format("{0:0}h{1:00}", Hours, Minutes);
return s;
}
}
}

View File

@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public enum Parameter
{
// Programmables and implemented options
T = 1,
RH = 2,
RampT = 3,
RampRH = 4,
PreTemp = 5,
Tlimit = 6,
// Client has option to proceed with next step
ProceedWithNextStep = 7,
}
public enum ProfileOption
{
// In every group XX00 - XX99, the option with the lowest int value is auto selected as default.
#region TSx : 1000-1999
// 1000 - 1099 : Startup options
TSx_StartSetupTest = 1000,
TSx_StartNoSetup = 1001,
// 1100 - 1199 : End mode options
TSx_EndModeOff = 1101,
TSx_EndModeHeatReturn = 1102,
TSx_EndModeSetup = 1103,
TSx_EndModeDefrost = 1104,
TSx_EndModeDry = 1105,
// 1200 - : others
TSx_PreTempManual = 1200,
TSx_PreTempAuto = 1201,
#endregion TSx : 1000-1999
#region PLxKPH : 2000-2999
// 2100 - 2199 : End mode options
PLxKPH_EndModeOff = 2100,
PLxKPH_EndModeHold = 2101,
#endregion PLxKPH : 2000-2999
#region LHL113 : 3000-3999
// 3100 - 3199 : End mode options
LHL113_EndModeOff = 3100,
LHL113_EndModeHold = 3101,
#endregion LHL113 : 3000-3999
#region HTS7057 : 4000-4999
// 4100 - 4199 : End mode options
HTS7057_EndModeOff = 4100,
HTS7057_EndModeHold = 4101,
#endregion HTS7057 : 4000-4999
#region Watlow988U : 5000-5999
// 5100 - 5199 : End mode options
Watlow988U_EndModeOff = 5100,
Watlow988U_EndModeHold = 5101,
#endregion Watlow988U : 5000-5999
}
public static class ProfileOptionExtensions
{
public static string ToStr(this ProfileOption me)
{
switch (me)
{
// TSx
case ProfileOption.TSx_StartNoSetup:
return "Start: no setup";
case ProfileOption.TSx_StartSetupTest:
return "Start: setup before test";
case ProfileOption.TSx_EndModeOff:
return "End: off";
case ProfileOption.TSx_EndModeHeatReturn:
return "End: return to heat";
case ProfileOption.TSx_EndModeSetup:
return "End: setup";
case ProfileOption.TSx_EndModeDefrost:
return "End: defrost";
case ProfileOption.TSx_EndModeDry:
return "End: dry";
case ProfileOption.TSx_PreTempAuto:
return "Pre-temp: Automatic";
case ProfileOption.TSx_PreTempManual:
return "Pre-temp: Manual";
// LHL-113
case ProfileOption.LHL113_EndModeOff:
return "End: off";
case ProfileOption.LHL113_EndModeHold:
return "End: hold last step";
// PLxKPH
case ProfileOption.PLxKPH_EndModeOff:
return "End: off";
case ProfileOption.PLxKPH_EndModeHold:
return "End: hold last step";
// HTS7057
case ProfileOption.HTS7057_EndModeOff:
return "End: off";
case ProfileOption.HTS7057_EndModeHold:
return "End: hold last step";
// Watlow988U
case ProfileOption.Watlow988U_EndModeOff:
return "End: off";
case ProfileOption.Watlow988U_EndModeHold:
return "End: hold last step";
default:
return string.Format("{0} [{1:0}]", me.ToString(), (int)me);
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Models")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Models")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("db13a74b-195a-45ef-af10-fb964d43466b")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

182
ChamChat/Models/Step.cs Normal file
View File

@@ -0,0 +1,182 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChamChat.Models
{
public class Step
{
/// <summary>
/// Create a new profile step
/// </summary>
/// <param name="Duration">Duration of step in minutes</param>
public Step(Double Duration)
{
_DurationMin = Duration;
}
private double _DurationMin = 0;
private int _PK = 0; // PK is index in Step list
private double _RH = 0; // RH = 0 means RH OFF
private double _T = 0;
private bool _RampCtrlRH = false;
private bool _RampCtrlT = false;
private double _PreTemp = 0;
private double _LimitT = 0;
public Double DurationMin { get { return _DurationMin; } set { _DurationMin = value; } }
public Int32 PK { get { return _PK; } set { _PK = value; } }
public Double RH { get { return _RH; } set { _RH = value; } }
public Double T { get { return _T; } set { _T = value; } }
public Boolean RampCtrlRH { get { return _RampCtrlRH; } set { _RampCtrlRH = value; } }
public Boolean RampCtrlT { get { return _RampCtrlT; } set { _RampCtrlT = value; } }
public Double PreTemp { get { return _PreTemp; } set { _PreTemp = value; } }
public Double LimitT { get { return _LimitT; } set { _LimitT = value; } }
public Int32 Hours { get { return (int)Math.Floor(_DurationMin / 60); } }
public Int32 Minutes { get { return (int)Math.Round(_DurationMin - 60 * Hours); } }
public string ToFormattedString()
{
string r ="";
if (_DurationMin > 60)
r = String.Format("{0:0} hours and {1:00} minutes ", Hours, Minutes);
else
r = String.Format("{0:0} minutes ", _DurationMin);
r += "\n";
if (_RampCtrlT)
r += String.Format("{0:0.0} °C (R-ctrl ON) ", _T);
else
r += String.Format("{0:0.0} °C (R-ctrl OFF) ", _T);
if (_RH > 0)
{
if (_RampCtrlRH)
r += String.Format("\n{0:0.0} %rh (R-ctrl ON)", _RH);
else
r += String.Format("\n{0:0.0} %rh (R-ctrl OFF)", _RH);
}
if (_PreTemp < double.MaxValue - 1 && !_RampCtrlT)
r += String.Format("\npre-T {0:0.0} °C, ", _PreTemp);
return r;
}
public override string ToString()
{
string r = String.Format("PK={0:00}: {1:0} min, ",_PK, _DurationMin);
if (_DurationMin >= 60)
r = String.Format("{0:0} hours & {1:00} minutes ", Hours,Minutes);
else
r = String.Format("{0:0} minutes ", _DurationMin);
r += "\n";
if (_RampCtrlT)
r += String.Format(" {0:0.0} °C (R-ctrl ON) ", _T);
else
r += String.Format(" {0:0.0} °C (R-ctrl OFF) ", _T);
if (_RH > 0)
{
if (_RampCtrlRH)
r += String.Format("\n{0:0.0} %rh (R-ctrl ON)", _RH);
else
r += String.Format("\n{0:0.0} %rh (R-ctrl OFF)", _RH);
}
if(!double.IsNaN(_PreTemp))
r += String.Format("\npre-T {0:0.0} °C, ", _PreTemp);
return r;
}
public Boolean HasRH
{
get
{
if (RH > 0)
return true;
return false;
}
}
public Step(String XML)
{
string fp = "<" + this.GetType().Namespace + "." + this.GetType().Name + ">";
if (!XML.Contains(fp))
throw new Exception(fp + " tag not found!");
try
{
_DurationMin = Double.Parse(XML.GetTags("_DurationMin"));
_PK = Int32.Parse(XML.GetTags("_PK"));
_RH = Double.Parse(XML.GetTags("_RH"));
_T = Double.Parse(XML.GetTags("_T"));
_RampCtrlRH = Boolean.Parse(XML.GetTags("_RampCtrlRH"));
_RampCtrlT = Boolean.Parse(XML.GetTags("_RampCtrlT"));
_PreTemp = Double.Parse(XML.GetTags("_PreTemp"));
_LimitT = Double.Parse(XML.GetTags("_LimitT"));
}
catch
{
throw new Exception(fp +": could not create instance from input string!");
}
}
public String XML
{
get
{
string xml = "";
xml += "<"+this.GetType().Namespace + "." + this.GetType().Name + ">";
xml += String.Format("<_DurationMin>{0:0.0}</_DurationMin>", _DurationMin);
xml += String.Format("<_PK>{0:0}</_PK>", _PK);
xml += String.Format("<_RH>{0:0.00}</_RH>", _RH);
xml += String.Format("<_T>{0:0.00}</_T>", _T);
xml += String.Format("<_RampCtrlRH>{0}</_RampCtrlRH>", _RampCtrlRH);
xml += String.Format("<_RampCtrlT>{0}</_RampCtrlT>", _RampCtrlT);
xml += String.Format("<_PreTemp>{0:0.00}</_PreTemp>", _PreTemp);
xml += String.Format("<_LimitT>{0:0.00}</_LimitT>", _LimitT);
xml += "</" + this.GetType().Namespace + "." + this.GetType().Name + ">";
return xml;
}
}
}
public static class StepExtensionMethods
{
public static Step DeepClone(this Step s)
{
Step r = new Step(s.DurationMin);
r.RH = s.RH;
r.T = s.T;
r.RampCtrlRH = s.RampCtrlRH;
r.RampCtrlT = s.RampCtrlT;
r.PreTemp = s.PreTemp;
r.LimitT = s.LimitT;
r.PK = s.PK;
return r;
}
}
}

323
ChamChat/Models/Task.cs Normal file
View File

@@ -0,0 +1,323 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Drawing;
using System.IO;
//using System.Windows.Forms;
using ChamChat.Models;
namespace ChamChat
{
public abstract class Task
{
private static string _LogFilePath;
private string _EventLogFile;
private string _DataTransferLogFile;
public static void SetLogPath(String path)
{
_LogFilePath = path + "\\TaskLogs";
if (!Directory.Exists(_LogFilePath))
Directory.CreateDirectory(_LogFilePath);
}
public Task(Client Client, Profile Profile)
{
_Profile = Profile;
_Client = Client;
ThreadPool.SetMaxThreads(1000, 1000);
}
private void InitDataTransferLog()
{
try
{
_Client.DataTransferLogs = new List<DataTransferLog>();
DateTime dt = DateTime.Now;
_DataTransferLogFile = _LogFilePath + "\\" + string.Format("Task_{0:00000}_{1:0000}{2:00}{3:00}.{4:00}{5:00}{6:00}.csv", _Client.MIDS, dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
using (StreamWriter sw = File.CreateText(_DataTransferLogFile))
{
sw.WriteLine(string.Format("Client : {0}", _Client.ToString()));
sw.WriteLine(string.Format("Created : {0:0000}-{1:00}-{2:00} @ {3:00}:{4:00} (system time)", dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute));
if (_Client.Interface != null)
sw.WriteLine(string.Format("Interface : {0}", _Client.Interface.ToString()));
else
sw.WriteLine("Interface : null");
sw.WriteLine(string.Format("Profile : {0}", _Profile.Title));
sw.WriteLine("");
sw.WriteLine("Timestamp; Command; Returndata");
}
_Client.DataTransferLogFile = _DataTransferLogFile;
}
catch { _Client.DataTransferLogFile = null; }
}
private void InitEventLog()
{
try
{
_EventLogs = new List<string>();
DateTime dt = DateTime.Now;
_EventLogFile = _LogFilePath + "\\" + string.Format("Task_{0:00000}_{1:0000}{2:00}{3:00}.{4:00}{5:00}{6:00}_events.csv", _Client.MIDS, dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
using (StreamWriter sw = File.CreateText(_EventLogFile))
{
sw.WriteLine(string.Format("Client : {0}", _Client.ToString()));
sw.WriteLine(string.Format("Created : {0:0000}-{1:00}-{2:00} @ {3:00}:{4:00} (system time)", dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute));
if (_Client.Interface != null)
sw.WriteLine(string.Format("Interface : {0}", _Client.Interface.ToString()));
else
sw.WriteLine("Interface : null");
sw.WriteLine(string.Format("Profile : {0}", _Profile.Title));
sw.WriteLine("");
}
}
catch { _EventLogFile = null; }
}
public String Description
{
get
{
string result = string.Format("{0:00000} : Profile '{1}'", _Client.MIDS, _Profile.Title);
return result;
}
}
List<String> _EventLogs; public List<String> EventLogs { get { return _EventLogs; } }
protected void AddEventLog(String message)
{
try
{
DateTime d = DateTime.Now;
string sTimestamp = String.Format("{0:0000}-{1:00}-{2:00} @ {3:00}:{4:00}:{5:00}", d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second);
string entry = String.Format("{0} : {1}", sTimestamp, message);
//if (_EventLogs.Count > 10000) // Prevent overflowing the list
//_EventLogs.RemoveAt(0);
_EventLogs.Add(entry);
if (_EventLogFile != null)
{
using (System.IO.StreamWriter sw = System.IO.File.AppendText(_EventLogFile))
{
sw.WriteLine(entry);
}
}
}
catch { }
}
public DateTime StartOfTask { get { return _startThread; } }
public Boolean IsRunningStandAlone { get { return _IsRunningStandAlone; } }
public Profile Profile { get { return _Profile; } }
public TaskStatus Status { get { return _Status; } }
public virtual Boolean IsStandAloneProgrammable(Profile profile)
{
return _Client.IsProgrammable(profile);
}
public abstract Boolean IsControlledProgrammable(Profile profile);
public String TaskProgress { get { return _TaskProgress; } }
public Boolean Start(Boolean isStandAlone)
{
if (_Status != TaskStatus.IsRunning)
{
InitDataTransferLog(); // Only init if also really started
InitEventLog();
_Status = TaskStatus.IsRunning;
if (isStandAlone)
{
_thread = new Thread(new ThreadStart(ThreadStandAlone));
}
else
{
_thread = new Thread(new ThreadStart(ThreadControlled));
}
_thread.Start();
_startThread = DateTime.Now;
_IsRunningStandAlone = isStandAlone;
if(isStandAlone)
AddEventLog("Stand alone task started");
else
AddEventLog("Controlled task started");
return true;
}
return false;
}
public Boolean Stop()
{
_Status = TaskStatus.AbortRequested;
DateTime OnStop = DateTime.Now;
while ((_isKicking) && (OnStop.AddSeconds(20) > DateTime.Now))
Thread.Sleep(100);
if (_isKicking)
{
_thread.Abort();
Thread.Sleep(100);
if (_thread.Join(2000))
_isKicking = false;
}
if (!_isKicking)
_Status = TaskStatus.Finished; // Set to finished because user invoked
return !_isKicking;
}
public Boolean NextStep()
{
_Status = TaskStatus.NextStepRequested;
DateTime OnStop = DateTime.Now;
while (_Status == TaskStatus.NextStepRequested && (OnStop.AddSeconds(30) > DateTime.Now))
Thread.Sleep(200);
return (_Status == TaskStatus.IsRunning);
}
protected String _TaskProgress;
protected Thread _thread;
protected Client _Client; public Client Client { get { return _Client; } }
protected DateTime _startThread;
protected Profile _Profile;
protected Boolean _isKicking;
protected TaskStatus _Status = TaskStatus.Starting;
protected abstract void ThreadControlled();
protected abstract void ThreadStandAlone();
protected Boolean _IsRunningStandAlone;
public Color StatusColor
{
get
{
Color color = Color.Black;
switch (_Status)
{
case TaskStatus.ExceptionOccured:
color = Color.Red;
break;
case TaskStatus.IsRunning:
color = Color.Green;
break;
case TaskStatus.Stopped:
color = Color.Orange;
break;
case TaskStatus.Finished:
color = Color.DarkGray;
break;
default:
color = Color.Black;
break;
}
return color;
}
}
}
public enum TaskStatus
{
Starting,
IsRunning,
AbortRequested,
Aborted,
Stopped,
Interrupted,
Finished,
ExceptionOccured,
NextStepRequested,
}
public static class TaskStatusExtensionMethods
{
public static string ToText(this TaskStatus s)
{
string result = s.ToString();
switch (s)
{
case TaskStatus.AbortRequested:
result = "Abort requested";
break;
case TaskStatus.ExceptionOccured:
result = "Exception occured";
break;
case TaskStatus.IsRunning:
result = "Running";
break;
case TaskStatus.NextStepRequested:
result = "Proceeding with next step";
break;
default:
result = s.ToString();
break;
}
return result;
}
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
663d5b02ff583775331c3da1b6ba08691b5f855f

View File

@@ -0,0 +1,6 @@
\\silicium\software\MASER software\Source\ChamChat\Models\bin\Release\ChamChat.Models.dll
\\silicium\software\MASER software\Source\ChamChat\Models\bin\Release\ChamChat.Models.pdb
\\silicium\software\MASER software\Source\ChamChat\Models\obj\Release\Models.csproj.AssemblyReference.cache
\\silicium\software\MASER software\Source\ChamChat\Models\obj\Release\Models.csproj.CoreCompileInputs.cache
\\silicium\software\MASER software\Source\ChamChat\Models\obj\Release\ChamChat.Models.dll
\\silicium\software\MASER software\Source\ChamChat\Models\obj\Release\ChamChat.Models.pdb