终端一体化运控平台
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

Control_MorkCL.cs 35 KiB

před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
před 1 rokem
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. 
  2. using BPA.Message.Enum;
  3. using BPASmartClient.CustomResource.Pages.Model;
  4. using BPASmartClient.CustomResource.UserControls.MessageShow;
  5. using BPASmartClient.Device;
  6. using BPASmartClient.MorkCL.HelpClass;
  7. using BPASmartClient.MorkCL.Model.DB;
  8. using BPASmartClient.MorkCL.Model.Json;
  9. using BPASmartClient.MorkCL.Server;
  10. using Newtonsoft.Json.Linq;
  11. using SqlSugar;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15. using System.Net.WebSockets;
  16. using System.Reflection;
  17. using System.Text;
  18. using System.Threading.Tasks;
  19. namespace BPASmartClient.MorkCL
  20. {
  21. public class Control_MorkCL : BaseDevice
  22. {
  23. public override DeviceClientType DeviceType => DeviceClientType.MORKCL;
  24. GVL_MorkCL morkCL = new GVL_MorkCL();
  25. Alarm alarm = new Alarm();
  26. /// <summary>
  27. /// 设备信息集合
  28. /// </summary>
  29. ConcurrentDictionary<EDeviceType, IModbus> devices { get; set; } = new();
  30. /// <summary>
  31. /// 任务集合
  32. /// </summary>
  33. ConcurrentDictionary<EDeviceType, TaskServer> TaskList { get; set; } = new();
  34. /// <summary>
  35. /// 炒锅1任务队列。
  36. /// </summary>
  37. ConcurrentQueue<TaskServer> FryingPan1TaskLsit { get; set; } = new();
  38. /// <summary>
  39. /// 炒锅2任务队列。
  40. /// </summary>
  41. ConcurrentQueue<TaskServer> FryingPan2TaskLsit { get; set; } = new();
  42. /// <summary>
  43. /// 高压锅任务队列。
  44. /// </summary>
  45. ConcurrentQueue<TaskServer> PressureCookerTaskLsit { get; set; } = new();
  46. public override void DoMain()
  47. {
  48. MonitorViewModel.DeviceId = DeviceId;
  49. SqliteHelper.GetInstance.Init();
  50. #region 读取本地文件数据
  51. Json<RecipesInfo>.Read();
  52. Json<ItemStorageInfo>.Read();
  53. Json<ConnectPar>.Read();
  54. #endregion
  55. //注册本地配方接收
  56. ActionManage.GetInstance.Register(new Action<object>(o =>
  57. {
  58. DeviceProcessLogShow($"接收到一个新配方任务。");
  59. if (o != null && o is ControlData cd)
  60. {
  61. morkCL.cds.Enqueue(cd);
  62. DeviceProcessLogShow($"新配方任务{cd.Id}解析完成,已加入配方队列。");
  63. }
  64. else
  65. {
  66. DeviceProcessLogShow($"新配方任务解析失败。");
  67. }
  68. }), NotifyTopic.FormulaDistribution);
  69. //初始化通讯对象
  70. devices.TryAdd(EDeviceType.炒锅1, new FryingPanServer());
  71. devices.TryAdd(EDeviceType.炒锅2, new FryingPanServer());
  72. devices.TryAdd(EDeviceType.机器人, new RobotServer());
  73. devices.TryAdd(EDeviceType.压力锅, new PressureCookerServer());
  74. devices.TryAdd(EDeviceType.外部设备, new OtherServer());
  75. #if !FORMAL
  76. devices[EDeviceType.炒锅1].Init(Json<ConnectPar>.Data.FryingPanIP1);
  77. devices[EDeviceType.炒锅2].Init(Json<ConnectPar>.Data.FryingPanIP2);
  78. devices[EDeviceType.机器人].Init(Json<ConnectPar>.Data.RobotIP);
  79. //devices[EDeviceType.压力锅].Init(Json<ConnectPar>.Data.PressureCookerIP);
  80. devices[EDeviceType.外部设备].Init(PortName:Json<ConnectPar>.Data.ESPortName);
  81. #endif
  82. ManualActionRegiester();
  83. }
  84. public override void MainTask()
  85. {
  86. //检查到有任务完成后将对已完成的任务进行清理
  87. var res = TaskList.FirstOrDefault(p => p.Value.IsComplete).Key;
  88. if (TaskList.ContainsKey(res))
  89. TaskList.TryRemove(res, out _);
  90. if (TaskList.IsEmpty)
  91. {
  92. morkCL.CanItemStorage = true;
  93. //ActionManage.GetInstance.Send("RefreshCanItemStorage", true);
  94. }
  95. else
  96. {
  97. morkCL.CanItemStorage = false;
  98. //ActionManage.GetInstance.Send("RefreshCanItemStorage", false);
  99. }
  100. //分配任务,这段程序必须写最后。
  101. if (morkCL.cds.Count > 0)
  102. {
  103. #region 修改为在下配方时选择使用哪个锅,这段程序不需要使用了。
  104. //var dishType = morkCL.cds.ElementAt(0).DishType;
  105. //var devieceType = EDeviceType.无;
  106. //if (dishType == Model.Recipe.EDishType.炒菜)
  107. //{
  108. // //如果任务队列里,炒锅1已经有任务了,就看炒锅2是否有任务,没任务就设置为炒锅2执行,如果两个锅都有任务则返回该次任务。
  109. // if (TaskList.ContainsKey(EDeviceType.炒锅1))
  110. // {
  111. // if (TaskList.ContainsKey(EDeviceType.炒锅2))
  112. // {
  113. // return;
  114. // }
  115. // else
  116. // { devieceType = EDeviceType.炒锅2; }
  117. // }
  118. // else
  119. // {
  120. // devieceType = EDeviceType.炒锅1;
  121. // }
  122. //}
  123. //else
  124. //{
  125. // devieceType = EDeviceType.压力锅;
  126. //}
  127. #endregion
  128. //这里判定主要是针对压力锅。
  129. if (!TaskList.ContainsKey(morkCL.cds.ElementAt(0).DeviceType))
  130. {
  131. if (morkCL.cds.TryDequeue(out ControlData cd))
  132. {
  133. //cd.DeviceType = devieceType;
  134. //cd.DeviceType = EDeviceType.炒锅1;
  135. TaskList.TryAdd(cd.DeviceType, new TaskServer());
  136. TaskList[cd.DeviceType].TaskName = $"{cd.DeviceType.ToString()}-{cd.Name}";
  137. TaskList[cd.DeviceType].RunTask = new Task(new Action(() => { FryingPanControl(cd.DeviceType, cd); }));
  138. TaskList[cd.DeviceType].RunTask.Start();
  139. }
  140. }
  141. }
  142. }
  143. private async void FryingPanControl(EDeviceType et, ControlData cd)
  144. {
  145. DeviceProcessLogShow($"【{et}】开始执行-{cd.Name} 任务");
  146. if (TaskList.ContainsKey(et) && TaskList[et].Cts.IsCancellationRequested) return;
  147. while (cd.ControlFuncs.Count > 0)
  148. {
  149. if (cd.ControlFuncs.TryDequeue(out FuncModel fm))
  150. {
  151. var device = (FryingPanServer)devices[et];
  152. var robot = (RobotServer)devices[EDeviceType.机器人];
  153. var otherDevice = (OtherServer)devices[EDeviceType.外部设备];
  154. int index = (ushort)et - 1;
  155. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}。");
  156. switch (fm.eFunc)
  157. {
  158. case EFunc.搅拌启动:
  159. device.StirStartOrStop = false;
  160. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入搅拌频率-{fm.funcPars.ElementAt(0).ParValue.ToString()}HZ。");
  161. device.MixingFrequencySet(fm.funcPars.ElementAt(0).ParValue.ToString());
  162. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入搅拌频率-{fm.funcPars.ElementAt(0).ParValue.ToString()}HZ完成。");
  163. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入开始搅拌。");
  164. device.StirStartOrStop = true;
  165. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入开始搅拌完成。");
  166. break;
  167. case EFunc.搅拌停止:
  168. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入停止搅拌。");
  169. device.StirStartOrStop = false;
  170. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入停止搅拌完成。");
  171. break;
  172. case EFunc.加热启动:
  173. device.HeatStartOrStop = false;
  174. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置加热挡位-【{fm.funcPars.ElementAt(0).ParValue.ToString()}】。");
  175. device.HeatingGearSet(fm.funcPars.ElementAt(0).ParValue.ToString());
  176. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置加热挡位完成,设置加热启动。");
  177. device.HeatStartOrStop = true;
  178. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置加热启动完成。");
  179. break;
  180. case EFunc.加热停止:
  181. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置加热停止。");
  182. device.HeatStartOrStop = false;
  183. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置加热停止完成。");
  184. break;
  185. case EFunc.添加调料:
  186. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-查找调料【{fm.funcPars.ElementAt(0).Id}】。");
  187. var Seasoning = SqliteHelper.GetInstance.GetSeasoning().FirstOrDefault(p => p.Id == fm.funcPars.ElementAt(0).Id);
  188. if (Seasoning != null)
  189. {
  190. device.FryingPanToSeasoningLoc = false;
  191. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅到调料投料位置。");
  192. device.FryingPanToSeasoningLoc = true;
  193. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅到调料投料位置完成。");
  194. //回到投料位置就复位。
  195. Thread.Sleep(50);
  196. device.FeedingSeasoningLocFB.Wait(Cts: TaskList[et].Cts);
  197. device.FryingPanToSeasoningLoc = false;
  198. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-炒锅已到达调料投料位置。");
  199. device.CuttingControl(Seasoning.Loc.ToString(), fm.funcPars.ElementAt(1).ParValue.ToString());
  200. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-执行下料,下料位置:{Seasoning.Loc.ToString()},下料重量:【{fm.funcPars.ElementAt(1).ParValue.ToString()}】。");
  201. }
  202. else
  203. {
  204. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-查找调料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】调料。任务取消。");
  205. TaskList[et].Cts.Cancel();
  206. }
  207. break;
  208. case EFunc.添加主料:
  209. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-查找主料【{fm.funcPars.ElementAt(0).Id}】。");
  210. if (float.TryParse(fm.funcPars.ElementAt(1).ParValue.ToString(), out float weight))
  211. {
  212. //查找主料库位符合条件的物料库位,主要根据物料ID和物料重量查找。
  213. var ingre_index = Array.FindIndex(Json<ItemStorageInfo>.Data.IngredientsStorage,
  214. item => item.MaterialID == fm.funcPars.ElementAt(0).Id/* && item.Weight == weight*/);
  215. if (ingre_index >= 0)
  216. {
  217. //device.CuttingControl(Seasoning.Loc.ToString(), fm.funcPars.ElementAt(1).ParValue.ToString());
  218. var ingredientes = Json<ItemStorageInfo>.Data.IngredientsStorage[ingre_index];
  219. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-执行下料,控制取{ingre_index + 1}库物料,下料名称:{ingredientes.Name.ToString()},下料重量:【{fm.funcPars.ElementAt(1).ParValue.ToString()}】。");
  220. device.FryingPanHome = false;
  221. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人任务【{(ingre_index + 1).ToString()}】,子任务【{et}】。");
  222. robot.RobotTaskControl((ingre_index + 1).ToString(), et);
  223. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人任务【{(ingre_index + 1).ToString()}】,子任务【{et}】完成。");
  224. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回投料位置。");
  225. device.FryingPanHome = true;
  226. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回投料位置完成。");
  227. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待炒锅到投料位置。");
  228. device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);//等待炒锅到投料位置
  229. device.FryingPanHome = false;
  230. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待炒锅到投料位置完成。");
  231. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待机器人到投料位置。");
  232. robot.MaterialPouringRequest[index].Wait(Cts: TaskList[et].Cts); //等待机器人到投料位置也就是发出倒料请求。
  233. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待机器人到投料位置完成。");
  234. //目前程序在炒锅在投料位置时,会自动发出允许倒料信息。
  235. //DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置允许机器人开始投料。");
  236. //robot.AllowPourVegetables(et);//允许机器人开始投料
  237. //DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置允许机器人开始投料完成。");
  238. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-开始等待机器人投料完成。");
  239. robot.MaterialPouringComplete[index].Wait(Cts: TaskList[et].Cts); //等待机器人投料完成
  240. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-机器人投料完成。");
  241. Json<ItemStorageInfo>.Data.IngredientsStorage[ingre_index] = new ItemStorage();
  242. Json<ItemStorageInfo>.Save();
  243. ActionManage.GetInstance.Send("RefreshItemStorage");
  244. }
  245. else
  246. {
  247. //TODO:暂定为直接取消任务,后期再说。
  248. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-查找主料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】主料。任务取消。");
  249. TaskList[et].Cts.Cancel();
  250. }
  251. }
  252. break;
  253. case EFunc.添加辅料:
  254. MaterialBase mb = SqliteHelper.GetInstance.GetAccessories().FirstOrDefault(p => p.Id == fm.funcPars.ElementAt(0).Id);
  255. if (mb != null)
  256. {
  257. //先复位变量。防止上一次是异常结束,设为True时,不会响应。
  258. device.FryingPanHome = false;
  259. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人任务【{(mb.Loc + 12).ToString()}】,子任务【{et}】。");
  260. robot.RobotTaskControl((mb.Loc + 12).ToString(), et);
  261. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人任务【{(mb.Loc + 12).ToString()}】,子任务【{et}】完成。");
  262. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回投料位置。");
  263. device.FryingPanHome = true;
  264. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回投料位置完成。");
  265. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待炒锅到投料位置。");
  266. device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);//等待炒锅到投料位置
  267. device.FryingPanHome = false;
  268. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待炒锅到投料位置完成。");
  269. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待机器人到投料位置。");
  270. robot.MaterialPouringRequest[index].Wait(Cts: TaskList[et].Cts); //等待机器人到投料位置
  271. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待机器人到投料位置完成。");
  272. //DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置允许机器人开始投料。");
  273. //robot.AllowPourVegetables(et);//允许机器人开始投料
  274. //DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置允许机器人开始投料完成。");
  275. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-开始等待机器人投料完成。");
  276. robot.MaterialPouringComplete[index].Wait(Cts: TaskList[et].Cts); //等待机器人投料完成
  277. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-机器人投料完成。");
  278. }
  279. else
  280. {
  281. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-查找主料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】辅料。任务取消。");
  282. TaskList[et].Cts.Cancel();
  283. }
  284. break;
  285. case EFunc.炒锅回原点位:
  286. device.FryingPanFeedingLoc = false;
  287. device.FryingPanHome = false;
  288. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回原点。");
  289. device.FryingPanHome = true;
  290. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回原点完成。");
  291. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待回原点完成。");
  292. device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);
  293. device.FryingPanHome = false;
  294. break;
  295. case EFunc.出餐启动:
  296. device.DiningOutStart = false;
  297. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人取空盆。");
  298. //TODO:暂时修改,后期优化。
  299. while (true)
  300. {
  301. var emptyPanIndex = Array.FindIndex(otherDevice.BoxDetection, i => i == true);
  302. if (emptyPanIndex >= 0)
  303. {
  304. robot.RobotTaskControl((21 + emptyPanIndex).ToString(), et);//取空盆
  305. break;
  306. }
  307. await Task.Delay(3000);
  308. DeviceProcessLogShow("无空盆,请添加空盆!");
  309. }
  310. //robot.RobotTaskControl("21", et);//取空盆
  311. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人取空盆完成,等待机器人到出菜位置。");
  312. robot.DiningOutRequest[index].Wait(Cts: TaskList[et].Cts);//等待机器人到出菜位置
  313. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-机器人已到出餐位置,出餐启动。");
  314. device.DiningOutStart = true;
  315. device.OutDinningSlowDownFlag.Wait(Cts: TaskList[et].Cts);
  316. robot.ModerateInPlace(et);
  317. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-到达出餐减速位。");
  318. device.OutDinningFinsh.Wait(Cts: TaskList[et].Cts);
  319. robot.DiningOutComplete(et);
  320. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-出餐完成。");
  321. //回到投料位置就复位。
  322. Thread.Sleep(50);
  323. device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);
  324. device.DiningOutStart = false;
  325. break;
  326. case EFunc.炒锅清洗:
  327. device.FryingPanClear = false;
  328. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅清洗。");
  329. device.FryingPanClear = true;
  330. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-炒锅清洗已写入。");
  331. Thread.Sleep(500);
  332. device.CleanFinish.Wait(Cts: TaskList[et].Cts);
  333. device.FryingPanClear = false;
  334. break;
  335. case EFunc.炒锅回调料投料位置:
  336. device.FryingPanToSeasoningLoc = false;
  337. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅到调料投料位置。");
  338. device.FryingPanToSeasoningLoc = true;
  339. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅到调料投料位置完成。");
  340. //回到投料位置就复位。
  341. Thread.Sleep(50);
  342. device.FeedingSeasoningLocFB.Wait(Cts: TaskList[et].Cts);
  343. device.FryingPanToSeasoningLoc = false;
  344. break;
  345. case EFunc.去指定炒制位:
  346. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置去指定炒制位。");
  347. device.SetStirFryingLoc(fm.funcPars.ElementAt(0).ParValue.ToString());
  348. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置去指定炒制位【{fm.funcPars.ElementAt(0).ParValue.ToString()}】完成。");
  349. break;
  350. case EFunc.炒制:
  351. if (int.TryParse(fm.funcPars.ElementAt(0).ParValue.ToString(), out int time))
  352. {
  353. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待炒制【{time}】秒。");
  354. Task.Delay(time * 1000).Wait(TaskList[et].Cts.Token);
  355. }
  356. DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-炒制完成。");
  357. break;
  358. default:
  359. break;
  360. }
  361. }
  362. }
  363. DeviceProcessLogShow($"【{et}】任务-{cd.Name} 执行完成");
  364. }
  365. public override void ReadData()
  366. {
  367. var propertyInfos = morkCL.GetType().GetProperties();
  368. var fryingPan1 = (FryingPanServer)devices[EDeviceType.炒锅1];
  369. var fryingPan2 = (FryingPanServer)devices[EDeviceType.炒锅2];
  370. var robot = (RobotServer)devices[EDeviceType.机器人];
  371. var pressureCooker = (PressureCookerServer)devices[EDeviceType.压力锅];
  372. var otherDevice = (OtherServer)devices[EDeviceType.外部设备];
  373. alarm.EStop1 = fryingPan1.EStopAlarm;
  374. alarm.FryingPanFowardLimit1 = fryingPan1.FryingPanFowardLimit;
  375. alarm.FryingPanReverseLimit1 = fryingPan1.FryingPanReverseLimit;
  376. alarm.FryingPanEncoderCommError1 = fryingPan1.FryingPanEncoderCommError;
  377. alarm.StirMotorCommError1 = fryingPan1.StirMotorCommError;
  378. alarm.RollingMotorCommError1 = fryingPan1.RollingMotorCommError;
  379. alarm.StirMotorError1 = fryingPan1.StirMotorErrorCode != "无故障" ? true : false;
  380. alarm.TurnMotorError1 = fryingPan1.TurnMotorErrorCode != "无故障" ? true : false;
  381. alarm.EStop2 = fryingPan2.EStopAlarm;
  382. alarm.FryingPanFowardLimit2 = fryingPan2.FryingPanFowardLimit;
  383. alarm.FryingPanReverseLimit2 = fryingPan2.FryingPanReverseLimit;
  384. alarm.FryingPanEncoderCommError2 = fryingPan2.FryingPanEncoderCommError;
  385. alarm.StirMotorCommError2 = fryingPan2.StirMotorCommError;
  386. alarm.RollingMotorCommError2 = fryingPan2.RollingMotorCommError;
  387. alarm.StirMotorError2 = fryingPan2.StirMotorErrorCode != "无故障" ? true : false;
  388. alarm.TurnMotorError2 = fryingPan2.TurnMotorErrorCode != "无故障" ? true : false;
  389. //这是字段。直接赋值
  390. morkCL.FeedingLocFB1 = fryingPan1.FeedingLocFB;
  391. morkCL.FeedingLocFB2 = fryingPan2.FeedingLocFB;
  392. morkCL.CleanFinish1 = fryingPan1.CleanFinish;
  393. morkCL.CleanFinish2 = fryingPan2.CleanFinish;
  394. morkCL.OutDinningFinsh1 = fryingPan1.OutDinningFinsh;
  395. morkCL.OutDinningFinsh2 = fryingPan2.OutDinningFinsh;
  396. morkCL.OutDinningSlowDownFlag1 = fryingPan1.OutDinningSlowDownFlag;
  397. morkCL.OutDinningSlowDownFlag2 = fryingPan2.OutDinningSlowDownFlag;
  398. morkCL.BoxDetection = otherDevice.BoxDetection;
  399. morkCL.IsIdle = robot.IsIdle;
  400. #if !FORMAL
  401. if (fryingPan1.FeedingLocFB)
  402. {
  403. robot.AllowPourVegetables(EDeviceType.炒锅1);
  404. }
  405. else
  406. {
  407. robot.DisablePourVegetables(EDeviceType.炒锅1);
  408. }
  409. if (fryingPan2.FeedingLocFB)
  410. {
  411. robot.AllowPourVegetables(EDeviceType.炒锅2);
  412. }
  413. else
  414. {
  415. robot.DisablePourVegetables(EDeviceType.炒锅2);
  416. }
  417. foreach (var property in propertyInfos)
  418. {
  419. var att = property.GetCustomAttribute<VariableMonitorAttribute>();
  420. if (att != null)
  421. {
  422. if (att.Notes.Contains("1号炒锅"))
  423. {
  424. var p = fryingPan1.GetType().GetProperty(property.Name.TrimEnd('1'));
  425. if (p != null)
  426. {
  427. property.SetValue(morkCL, p.GetValue(fryingPan1));
  428. }
  429. }
  430. else if (att.Notes.Contains("2号炒锅"))
  431. {
  432. var p = fryingPan2.GetType().GetProperty(property.Name.TrimEnd('2'));
  433. if (p != null)
  434. {
  435. property.SetValue(morkCL, p.GetValue(fryingPan2));
  436. }
  437. }
  438. else if (att.Notes.Contains("机器人"))
  439. {
  440. var p = robot.GetType().GetProperty(property.Name);
  441. if (p != null)
  442. {
  443. property.SetValue(morkCL, p.GetValue(robot));
  444. }
  445. }
  446. else if (att.Notes.Contains("电子秤"))
  447. {
  448. var p = otherDevice.GetType().GetProperty(property.Name);
  449. if (p != null)
  450. {
  451. var res = p.GetValue(otherDevice);
  452. property.SetValue(morkCL, res);
  453. if (p.Name== "CurrentWeight")
  454. {
  455. ActionManage.GetInstance.Send("SendCurrentWeight", res);
  456. }
  457. }
  458. }
  459. else if (att.Notes.Contains("高压锅"))
  460. {
  461. var p = pressureCooker.GetType().GetProperty(property.Name);
  462. if (p != null)
  463. {
  464. property.SetValue(morkCL, p.GetValue(pressureCooker));
  465. }
  466. }
  467. }
  468. }
  469. #endif
  470. }
  471. public override void ResetProgram()
  472. {
  473. morkCL = null;
  474. morkCL = new GVL_MorkCL();
  475. }
  476. public override void SimOrder()
  477. {
  478. }
  479. public override void Stop()
  480. {
  481. }
  482. void ManualActionRegiester()
  483. {
  484. //主料入库委托。
  485. ActionManage.GetInstance.Register((object o) =>
  486. {
  487. if (!morkCL.CanItemStorage)
  488. {
  489. MessageNotify.GetInstance.ShowDialog("当前有炒菜任务正在排队,为避免影响菜品口味,不可入库,请稍后再试。", DialogType.Warning);
  490. NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "入库失败", $"物料入库失败,当前正在制作菜品。");
  491. return;
  492. }
  493. TaskManage.GetInstance.Start(() =>
  494. {
  495. if (o != null && o is IngredientsTB ingredients)
  496. {
  497. var index = Array.FindIndex(Json<ItemStorageInfo>.Data.IngredientsStorage, i => i.IsEmploy == false);
  498. if (index >= 0)
  499. {
  500. var item = Json<ItemStorageInfo>.Data.IngredientsStorage[index];
  501. item.MaterialID = ingredients.Id;
  502. item.Name = ingredients.Name;
  503. item.IsEmploy = true;
  504. item.Weight = ((OtherServer)devices[EDeviceType.外部设备]).CurrentWeight;
  505. var loc = (index + 1).ToString();
  506. //var robot = (RobotServer)devices[EDeviceType.机器人];
  507. //robot.WarehousingControl(loc);
  508. //robot.WarehousingComplete[(Convert.ToInt32(loc) - 1)].Wait();
  509. Json<ItemStorageInfo>.Save();
  510. ActionManage.GetInstance.Send("RefreshItemStorage");
  511. DeviceProcessLogShow($"物料{ingredients.Name},ID:[{ingredients.Id}]入库成功。");
  512. Application.Current.Dispatcher.Invoke(() =>
  513. {
  514. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, Application.Current.MainWindow, "入库成功", $"物料{ingredients.Name}入库成功。");
  515. });
  516. return;
  517. }
  518. else
  519. {
  520. Application.Current.Dispatcher.Invoke(() =>
  521. {
  522. NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "入库失败", $"物料库已满。");
  523. });
  524. }
  525. }
  526. else
  527. {
  528. Application.Current.Dispatcher.Invoke(() =>
  529. {
  530. NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "入库失败", $"物料入库失败。");
  531. });
  532. }
  533. }, "ItemStorageTask");
  534. }, NotifyTopic.ItemStorage, true);
  535. #region 暂时弃用
  536. ActionManage.GetInstance.Register((object location) =>
  537. {
  538. var loc = location.ToString();
  539. if (!String.IsNullOrEmpty(loc) && loc.Length >= 0)
  540. {
  541. var robot = (RobotServer)devices[EDeviceType.机器人];
  542. //Thread.Sleep(5000);
  543. robot.WarehousingControl(loc);
  544. //会卡死。
  545. robot.WarehousingComplete[(Convert.ToInt32(loc) - 1)].Wait();
  546. }
  547. }, "ItemStorage", true);
  548. #endregion
  549. ActionManage.GetInstance.Register((object o) =>
  550. {
  551. if (o!=null && o is WriteModel<bool> write)
  552. {
  553. devices[write.DeviceType].WriteValue<bool>(write.Address, write.Value);
  554. DeviceProcessLogShow($"设备[{write.DeviceType}]--手动写入地址[{write.Address}],值[{write.Value}]");
  555. }
  556. }, "WriteBool", true);
  557. ActionManage.GetInstance.Register((object o) =>
  558. {
  559. if (o != null && o is WriteModel<ushort> write)
  560. {
  561. devices[write.DeviceType].WriteValue<ushort>(write.Address, write.Value);
  562. DeviceProcessLogShow($"设备[{write.DeviceType}]--手动写入地址[{write.Address}],值[{write.Value}]");
  563. }
  564. }, "WriteUshort", true);
  565. }
  566. }
  567. }