Recipe.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.ComponentModel;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Linq;
  8. using Newtonsoft.Json;
  9. using Newtonsoft.Json.Converters;
  10. using Venus_Core.Attributes;
  11. namespace Venus_Core
  12. {
  13. public enum RecipeType
  14. {
  15. Chuck,
  16. DeChuck,
  17. Process,
  18. Clean,
  19. }
  20. public enum StepType
  21. {
  22. Time,
  23. Stable,
  24. EndPoint,
  25. OverEtch,
  26. }
  27. public enum ProcessModule
  28. {
  29. Pressure,
  30. TCP, // Transformer Coupled Plasma (转换耦合等离子)
  31. Bias,
  32. Gas,
  33. ESC,
  34. Process,
  35. Compound,
  36. }
  37. public enum GeneratorMode
  38. {
  39. CW,
  40. Pulsing,
  41. }
  42. public enum PressureUnitMode
  43. {
  44. Pressure,
  45. Valve
  46. }
  47. public enum Suspect
  48. {
  49. Origin,
  50. Position1,
  51. Position2,
  52. Position3,
  53. Position4,
  54. Position5
  55. }
  56. public enum TargetMode
  57. {
  58. Step,
  59. Cycle
  60. }
  61. public enum ToleranceMode
  62. {
  63. None,
  64. Value,
  65. Percent
  66. }
  67. public enum MatchWorkMode
  68. {
  69. Auto,
  70. Manual
  71. }
  72. public class RecipeHead : INotifyPropertyChanged
  73. {
  74. private string m_name;
  75. [IsOnlyRead]
  76. public string Name
  77. {
  78. get { return m_name; }
  79. set { m_name = value; InvokePropertyChanged("Name"); }
  80. }
  81. private string _Version = "TestVersion";
  82. public string Version
  83. {
  84. get { return _Version; }
  85. set { _Version = value; InvokePropertyChanged("Version"); }
  86. }
  87. private JetChamber _ChamberType = JetChamber.None;
  88. [JsonConverter(typeof(StringEnumConverter))]
  89. [IsOnlyRead]
  90. public JetChamber ChamberType
  91. {
  92. get { return _ChamberType; }
  93. set { _ChamberType = value; InvokePropertyChanged("ChamberType"); }
  94. }
  95. private RecipeType m_Type;
  96. [JsonConverter(typeof(StringEnumConverter))]
  97. [IsOnlyRead]
  98. public RecipeType Type
  99. {
  100. get { return m_Type; }
  101. set { m_Type = value; InvokePropertyChanged("Type"); }
  102. }
  103. private string m_ChunckRecipe;
  104. public string ChuckRecipe
  105. {
  106. get { return m_ChunckRecipe; }
  107. set { m_ChunckRecipe = value; InvokePropertyChanged("ChuckRecipe"); }
  108. }
  109. private string m_DechuckRecipe;
  110. public string DechuckRecipe
  111. {
  112. get { return m_DechuckRecipe; }
  113. set { m_DechuckRecipe = value; InvokePropertyChanged("DechuckRecipe"); }
  114. }
  115. private bool m_IsShowTolerance;
  116. public bool IsShowTolerance
  117. {
  118. get { return m_IsShowTolerance; }
  119. set { m_IsShowTolerance = value; InvokePropertyChanged("IsShowTolerance"); }
  120. }
  121. private string m_CreateTime;
  122. [IsOnlyRead]
  123. public string CreateTime
  124. {
  125. get { return m_CreateTime; }
  126. set { m_CreateTime = value; InvokePropertyChanged("CreateTime"); }
  127. }
  128. private string m_EditTime;
  129. [IsOnlyRead]
  130. public string EditTime
  131. {
  132. get { return m_EditTime; }
  133. set { m_EditTime = value; InvokePropertyChanged("EditTime"); }
  134. }
  135. private string m_LastModifiedBy;
  136. [IsOnlyRead]
  137. public string LastModifiedBy
  138. {
  139. get { return m_LastModifiedBy; }
  140. set { m_LastModifiedBy = value; InvokePropertyChanged("LastModifiedBy"); }
  141. }
  142. private string m_Barcode;
  143. public string Barcode
  144. {
  145. get { return m_Barcode; }
  146. set { m_Barcode = value; InvokePropertyChanged("Barcode"); }
  147. }
  148. private string m_BasePressure;
  149. public string BasePressure
  150. {
  151. get { return m_BasePressure; }
  152. set { m_BasePressure = value; InvokePropertyChanged("BasePressure"); }
  153. }
  154. private string m_Temperature;
  155. public string Temperature
  156. {
  157. get { return m_Temperature; }
  158. set { m_Temperature = value; InvokePropertyChanged("Temperature"); }
  159. }
  160. private int m_RFHoldTime = 1000;
  161. [CustomName("RF HoldTime(s)")]
  162. public int RFHoldTime
  163. {
  164. get { return m_RFHoldTime; }
  165. set { m_RFHoldTime = value; InvokePropertyChanged("RFHoldTime"); }
  166. }
  167. private int m_BiasRFHoldTime = 1000;
  168. [CustomName("BiasRF HoldTime(s)")]
  169. public int BiasRFHoldTime
  170. {
  171. get { return m_BiasRFHoldTime; }
  172. set { m_BiasRFHoldTime = value; InvokePropertyChanged("BiasRFHoldTime"); }
  173. }
  174. private string m_Comment;
  175. public string Comment
  176. {
  177. get { return m_Comment; }
  178. set { m_Comment = value; InvokePropertyChanged("Comment"); }
  179. }
  180. public event PropertyChangedEventHandler PropertyChanged;
  181. public void InvokePropertyChanged(string propertyName)
  182. {
  183. if (PropertyChanged != null)
  184. {
  185. PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
  186. }
  187. }
  188. }
  189. public abstract class ProcessUnitBase
  190. {
  191. [JsonIgnore]
  192. public Func<ProcessUnitBase, RecipeStep, RState> checker;
  193. [JsonIgnore]
  194. public Func<ProcessUnitBase, RecipeStep, RState> starter;
  195. [JsonIgnore]
  196. public Action<ProcessUnitBase, RecipeStep> end;
  197. //[JsonIgnore]
  198. //public string Name { get; set; }
  199. //[JsonIgnore]
  200. //public ProcessModule Moudle { get; set; }
  201. public RState Start(RecipeStep step)
  202. {
  203. if (starter != null)
  204. return starter(this, step);
  205. return RState.Running;
  206. }
  207. public RState Run(RecipeStep step)
  208. {
  209. if (checker != null)
  210. return checker(this, step);
  211. return RState.Running;
  212. }
  213. public void End(RecipeStep step)
  214. {
  215. if (end != null)
  216. end(this, step);
  217. }
  218. public virtual Dictionary<string,float> GetFDCItems()
  219. {
  220. return null;
  221. }
  222. }
  223. [Serializable]
  224. public class RecipeStep : INotifyPropertyChanged
  225. {
  226. [JsonIgnore]
  227. public Func<RecipeStep, RState> checker;
  228. [JsonIgnore]
  229. public Func<RecipeStep, RState> starter;
  230. [JsonIgnore]
  231. public Func<RecipeStep, RState> ender;
  232. private int m_StepNo = 1;
  233. [IsOnlyRead]
  234. public int StepNo
  235. {
  236. get { return m_StepNo; }
  237. set { m_StepNo = value; InvokePropertyChanged("StepNo"); }
  238. }
  239. private StepType m_StepType;
  240. [JsonConverter(typeof(StringEnumConverter))]
  241. public StepType Type
  242. {
  243. get { return m_StepType; }
  244. set { m_StepType = value; InvokePropertyChanged("Type"); }
  245. }
  246. private int m_Time;
  247. [CustomName("Time(s)")]
  248. public int Time
  249. {
  250. get { return m_Time; }
  251. set { m_Time = value; InvokePropertyChanged("Time"); }
  252. }
  253. private string m_Description;
  254. public string Description
  255. {
  256. get { return m_Description; }
  257. set { m_Description = value; InvokePropertyChanged("Description"); }
  258. }
  259. private string m_EPDConfigName;
  260. public string EPDConfig
  261. {
  262. get { return m_EPDConfigName; }
  263. set { m_EPDConfigName = value; InvokePropertyChanged("EPDConfig"); }
  264. }
  265. private int m_MinEndPointTime;
  266. [CustomName("MinEndPointTime(s)")]
  267. public int MinEndPointTime
  268. {
  269. get { return m_MinEndPointTime; }
  270. set { m_MinEndPointTime = value; InvokePropertyChanged("MinEndPointTime"); }
  271. }
  272. private int m_MaxEndPointTime;
  273. [CustomName("MaxEndPointTime(s)")]
  274. public int MaxEndPointTime
  275. {
  276. get { return m_MaxEndPointTime; }
  277. set { m_MaxEndPointTime = value; InvokePropertyChanged("MaxEndPointTime"); }
  278. }
  279. //private bool m_EnableRamp;
  280. //public bool EnableRamp
  281. //{
  282. // get { return m_EnableRamp; }
  283. // set { m_EnableRamp = value; InvokePropertyChanged("EnableRamp"); }
  284. //}
  285. private int m_OverEtchPercent;
  286. [CustomName("OverEtchPercent(%)")]
  287. public int OverEtchPercent
  288. {
  289. get { return m_OverEtchPercent; }
  290. set { m_OverEtchPercent = value; InvokePropertyChanged("OverEtchPercent"); }
  291. }
  292. private bool m_CycleStart;
  293. public bool CycleStart
  294. {
  295. get { return m_CycleStart; }
  296. set { m_CycleStart = value; InvokePropertyChanged("CycleStart"); }
  297. }
  298. private bool m_CycleEnd;
  299. public bool CycleEnd
  300. {
  301. get { return m_CycleEnd; }
  302. set { m_CycleEnd = value; InvokePropertyChanged("CycleEnd"); }
  303. }
  304. private int m_CycleNumber;
  305. public int CycleNumber
  306. {
  307. get { return m_CycleNumber; }
  308. set { m_CycleNumber = value; InvokePropertyChanged("CycleNumber"); }
  309. }
  310. private ObservableCollection<object> lstUnit = new ObservableCollection<object>();
  311. public ObservableCollection<object> LstUnit
  312. {
  313. get { return lstUnit; }
  314. set { lstUnit = value; InvokePropertyChanged("LstUnit"); }
  315. }
  316. private Stopwatch _stepTimer = new Stopwatch();
  317. public long ElapsedTime()
  318. {
  319. return _stepTimer.ElapsedMilliseconds;
  320. }
  321. public void StartStepTimer()
  322. {
  323. _stepTimer.Restart();
  324. }
  325. //private long _lastEPDStepTime = 0;
  326. //public void RecordEPDStepTime()
  327. //{
  328. // _lastEPDStepTime = _stepTimer.ElapsedMilliseconds;
  329. //}
  330. //public long GetLastEPDStepTime()
  331. //{
  332. // return _lastEPDStepTime;
  333. //}
  334. public RState Start()
  335. {
  336. starter(this);
  337. foreach (var unit in lstUnit)
  338. {
  339. var processUnit = unit as ProcessUnitBase;
  340. if (processUnit != null)
  341. {
  342. var state = processUnit.Start(this);
  343. if (state != RState.Running)
  344. return state;
  345. }
  346. else
  347. return RState.Failed;
  348. }
  349. return RState.Running;
  350. }
  351. public RState Start(int steps, int currentstep)
  352. {
  353. starter(this);
  354. foreach (var unit in lstUnit)
  355. {
  356. var processUnit = unit as ProcessUnitBase;
  357. if (processUnit != null)
  358. {
  359. var state = processUnit.Start(this);
  360. if (state != RState.Running)
  361. return state;
  362. }
  363. else
  364. return RState.Failed;
  365. }
  366. return RState.Running;
  367. }
  368. public RState Run()
  369. {
  370. var checkerState= checker(this);
  371. if (checkerState == RState.End)
  372. {
  373. return RState.End;
  374. }
  375. else if (checkerState == RState.Failed)
  376. {
  377. return RState.Failed;
  378. }
  379. bool bStable = true;
  380. foreach (var unit in lstUnit)
  381. {
  382. var processUnit = unit as ProcessUnitBase;
  383. if (processUnit != null)
  384. {
  385. var state = processUnit.Run(this);
  386. if (Type == StepType.Stable)
  387. {
  388. if (state != RState.Running && state != RState.End)
  389. return state;
  390. if (state == RState.Running)
  391. bStable = false;
  392. }
  393. else
  394. {
  395. if (state != RState.Running)
  396. return state;
  397. }
  398. }
  399. else
  400. return RState.Failed;
  401. }
  402. return (Type == StepType.Stable && bStable) ? RState.End : RState.Running;
  403. }
  404. public void End()
  405. {
  406. foreach (var unit in lstUnit)
  407. {
  408. var processUnit = unit as ProcessUnitBase;
  409. if (processUnit != null)
  410. {
  411. processUnit.End(this);
  412. }
  413. }
  414. ender(this);
  415. }
  416. public double RampFactor()
  417. {
  418. return _stepTimer.ElapsedMilliseconds / (Time * 1000.0);
  419. }
  420. public void AppendUnit(ProcessUnitBase unit)
  421. {
  422. lstUnit.Append(unit);
  423. }
  424. public event PropertyChangedEventHandler PropertyChanged;
  425. public void InvokePropertyChanged(string propertyName)
  426. {
  427. if (PropertyChanged != null)
  428. {
  429. PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
  430. }
  431. }
  432. }
  433. public class Recipe : INotifyPropertyChanged
  434. {
  435. private RecipeHead m_Header = new RecipeHead();
  436. public RecipeHead Header
  437. {
  438. get { return m_Header; }
  439. set { m_Header = value; InvokePropertyChanged("Header"); }
  440. }
  441. private ObservableCollection<RecipeStep> m_Steps;
  442. public ObservableCollection<RecipeStep> Steps
  443. {
  444. get { return m_Steps; }
  445. set { m_Steps = value; InvokePropertyChanged("Steps"); }
  446. }
  447. public static Recipe Load(string recipeFile)
  448. {
  449. var recipe = JsonConvert.DeserializeObject<Recipe>(recipeFile);
  450. if (recipe == null)
  451. {
  452. return null;
  453. }
  454. foreach (var step in recipe.Steps)
  455. {
  456. ObservableCollection<object> unit = new ObservableCollection<object>();
  457. for (int i = 0; i < step.LstUnit.Count; i++)
  458. {
  459. string value = step.LstUnit[i].ToString();
  460. string[] striparr = value.Split(new string[] { "\r\n" }, StringSplitOptions.None);
  461. string item1 = striparr[1].Remove(0, 15);
  462. string item2 = item1.Remove(item1.Length - 2, 2);
  463. switch (item2)
  464. {
  465. case "PressureModeUnit":
  466. unit.Add(JsonConvert.DeserializeObject<PressureByPressureModeUnit>(step.LstUnit[i].ToString()));
  467. break;
  468. //case "PressureByValveModeUnit":
  469. // unit.Add(JsonConvert.DeserializeObject<PressureByValveModeUnit>(step.LstUnit[i].ToString()));
  470. // break;
  471. case "TCPUnit":
  472. unit.Add(JsonConvert.DeserializeObject<TCPUnit>(step.LstUnit[i].ToString()));
  473. break;
  474. case "BiasUnit":
  475. unit.Add(JsonConvert.DeserializeObject<BiasUnit>(step.LstUnit[i].ToString()));
  476. break;
  477. case "GasControlUnit":
  478. unit.Add(JsonConvert.DeserializeObject<GasControlUnit>(step.LstUnit[i].ToString()));
  479. break;
  480. case "ESCHVUnit":
  481. unit.Add(JsonConvert.DeserializeObject<ESCHVUnit>(step.LstUnit[i].ToString()));
  482. break;
  483. case "ProcessKitUnit":
  484. unit.Add(JsonConvert.DeserializeObject<ProcessKitUnit>(step.LstUnit[i].ToString()));
  485. break;
  486. case "HeaterUnit":
  487. unit.Add(JsonConvert.DeserializeObject<HeaterUnit>(step.LstUnit[i].ToString()));
  488. break;
  489. case "RFBoxUnit":
  490. unit.Add(JsonConvert.DeserializeObject<RFBoxUnit>(step.LstUnit[i].ToString()));
  491. break;
  492. case "GasUnit":
  493. unit.Add(JsonConvert.DeserializeObject<Kepler2200GasControlUnit>(step.LstUnit[i].ToString()));
  494. break;
  495. case "SEGasControlUnit":
  496. unit.Add(JsonConvert.DeserializeObject<VenusSEGasControlUnit>(step.LstUnit[i].ToString()));
  497. break;
  498. case "DEGasControlUnit":
  499. unit.Add(JsonConvert.DeserializeObject<VenusDEGasControlUnit>(step.LstUnit[i].ToString()));
  500. break;
  501. case "Magnet":
  502. unit.Add(JsonConvert.DeserializeObject<MagnetUnit>(step.LstUnit[i].ToString()));
  503. break;
  504. }
  505. }
  506. step.LstUnit.Clear();
  507. unit.ToList().ForEach(x =>
  508. {
  509. step.LstUnit.Add(x);
  510. });
  511. }
  512. return recipe;
  513. }
  514. public bool Validate()
  515. {
  516. return true;
  517. }
  518. public bool Save(string recipeFile)
  519. {
  520. return true;
  521. }
  522. public event PropertyChangedEventHandler PropertyChanged;
  523. public void InvokePropertyChanged(string propertyName)
  524. {
  525. if (PropertyChanged != null)
  526. {
  527. PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
  528. }
  529. }
  530. }
  531. public class RecipeUnity
  532. {
  533. public static string ConvertJsonString(string str)
  534. {
  535. JsonSerializer serializer = new JsonSerializer();
  536. TextReader tr = new StringReader(str);
  537. JsonTextReader jtr = new JsonTextReader(tr);
  538. object obj = serializer.Deserialize(jtr);
  539. if (obj != null)
  540. {
  541. StringWriter textWriter = new StringWriter();
  542. JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)
  543. {
  544. Formatting = Newtonsoft.Json.Formatting.Indented,
  545. Indentation = 4,
  546. IndentChar = ' '
  547. };
  548. serializer.Serialize(jsonWriter, obj);
  549. return textWriter.ToString();
  550. }
  551. else
  552. {
  553. return str;
  554. }
  555. }
  556. public static string RecipeToString(Recipe recipe)
  557. {
  558. return JsonConvert.SerializeObject(recipe);
  559. }
  560. public static String CreateRecipe(JetChamber currentChamber, RecipeType recipeType, string recipeName)
  561. {
  562. Recipe recipe = new Recipe();
  563. recipe.Header = new RecipeHead();
  564. recipe.Header.CreateTime = DateTime.Now.ToString();
  565. recipe.Header.EditTime = DateTime.Now.ToString();
  566. recipe.Header.Type = recipeType;
  567. recipe.Header.ChamberType = currentChamber;
  568. recipe.Header.Name = recipeName;
  569. recipe.Header.LastModifiedBy = "Admin";
  570. recipe.Steps = new ObservableCollection<RecipeStep>();
  571. RecipeStep recipeStep = new RecipeStep();
  572. recipeStep.LstUnit = GetAllUnits(currentChamber, recipeType);
  573. recipe.Steps.Add(recipeStep);
  574. var recipeString = JsonConvert.SerializeObject(recipe);
  575. return recipeString;
  576. }
  577. public static ObservableCollection<object> GetAllUnits(JetChamber jetChamber, RecipeType recipeType)
  578. {
  579. ObservableCollection<object> LstUnit = new ObservableCollection<object>();
  580. switch (jetChamber)
  581. {
  582. //case JetChamber.Venus:
  583. // if (recipeType == RecipeType.Clean)
  584. // {
  585. // foreach (var item in Enum.GetValues(typeof(VenusCleanRecipeUnits)))
  586. // {
  587. // Type t = Type.GetType($"Venus_Core.{item.ToString()}");
  588. // var obj = System.Activator.CreateInstance(t);
  589. // LstUnit.Add(obj);
  590. // }
  591. // }
  592. // else
  593. // {
  594. // foreach (var item in Enum.GetValues(typeof(VenusUnits)))
  595. // {
  596. // Type t = Type.GetType($"Venus_Core.{item.ToString()}");
  597. // var obj = System.Activator.CreateInstance(t);
  598. // LstUnit.Add(obj);
  599. // }
  600. // }
  601. // break;
  602. case JetChamber.Kepler2300:
  603. if (recipeType == RecipeType.Clean)
  604. {
  605. foreach (var item in Enum.GetValues(typeof(Kepler2300CleanRecipeUints)))
  606. {
  607. Type t = Type.GetType($"Venus_Core.{item.ToString()}");
  608. var obj = System.Activator.CreateInstance(t);
  609. LstUnit.Add(obj as ProcessUnitBase);
  610. }
  611. }
  612. else
  613. {
  614. foreach (var item in Enum.GetValues(typeof(Kepler2300Uints)))
  615. {
  616. Type t = Type.GetType($"Venus_Core.{item.ToString()}");
  617. var obj = System.Activator.CreateInstance(t);
  618. LstUnit.Add(obj as ProcessUnitBase);
  619. }
  620. }
  621. break;
  622. case JetChamber.Kepler2200A:
  623. foreach (var item in Enum.GetValues(typeof(Kepler2200AUnits)))
  624. {
  625. Type t = Type.GetType($"Venus_Core.{item.ToString()}");
  626. var obj = System.Activator.CreateInstance(t);
  627. LstUnit.Add(obj as ProcessUnitBase);
  628. }
  629. break;
  630. case JetChamber.Kepler2200B:
  631. foreach (var item in Enum.GetValues(typeof(Kepler2200BUnits)))
  632. {
  633. Type t = Type.GetType($"Venus_Core.{item.ToString()}");
  634. var obj = System.Activator.CreateInstance(t);
  635. LstUnit.Add(obj as ProcessUnitBase);
  636. }
  637. break;
  638. case JetChamber.VenusSE:
  639. foreach (var item in Enum.GetValues(typeof(VenusSEUnits)))
  640. {
  641. Type t = Type.GetType($"Venus_Core.{item.ToString()}");
  642. var obj = System.Activator.CreateInstance(t);
  643. LstUnit.Add(obj as ProcessUnitBase);
  644. }
  645. break;
  646. case JetChamber.VenusDE:
  647. foreach (var item in Enum.GetValues(typeof(VenusDEUnits)))
  648. {
  649. Type t = Type.GetType($"Venus_Core.{item.ToString()}");
  650. var obj = System.Activator.CreateInstance(t);
  651. LstUnit.Add(obj as ProcessUnitBase);
  652. }
  653. break;
  654. }
  655. return LstUnit;
  656. }
  657. }
  658. }