终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Control_MorkCL.cs 69 KiB

1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264
  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 Opc.Ua;
  12. using SqlSugar;
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Linq;
  16. using System.Net.WebSockets;
  17. using System.Reflection;
  18. using System.Text;
  19. using System.Threading.Tasks;
  20. namespace BPASmartClient.MorkCL
  21. {
  22. public class Control_MorkCL : BaseDevice
  23. {
  24. public override DeviceClientType DeviceType => DeviceClientType.MORKCL;
  25. GVL_MorkCL morkCL = new GVL_MorkCL();
  26. Alarm alarm = new Alarm();
  27. /// <summary>
  28. /// 设备信息集合
  29. /// </summary>
  30. ConcurrentDictionary<EDeviceType, IModbus> devices { get; set; } = new();
  31. /// <summary>
  32. /// 任务集合
  33. /// </summary>
  34. ConcurrentDictionary<EDeviceType, TaskServer> TaskList { get; set; } = new();
  35. List<PropertyInfo>? propertyInfos;
  36. public override void DoMain()
  37. {
  38. MonitorViewModel.DeviceId = DeviceId;
  39. SqliteHelper.GetInstance.Init();
  40. #region 读取本地文件数据
  41. Json<RecipesInfo>.Read();
  42. Json<ItemStorageInfo>.Read();
  43. Json<ConnectPar>.Read();
  44. #endregion
  45. //注册本地配方接收
  46. ActionManage.GetInstance.Register(new Action<object>(o =>
  47. {
  48. DeviceProcessLogShow($"接收到一个新配方任务。");
  49. if (o != null && o is ControlData cd)
  50. {
  51. morkCL.cds.Enqueue(cd);
  52. DeviceProcessLogShow($"新配方任务{cd.Id}解析完成,已加入配方队列。");
  53. }
  54. else
  55. {
  56. DeviceProcessLogShow($"新配方任务解析失败。");
  57. }
  58. }), NotifyTopic.FormulaDistribution);
  59. //初始化通讯对象
  60. devices.TryAdd(EDeviceType.炒锅1, new FryingPanServer());
  61. devices.TryAdd(EDeviceType.炒锅2, new FryingPanServer());
  62. devices.TryAdd(EDeviceType.机器人, new RobotServer());
  63. devices.TryAdd(EDeviceType.压力锅, new PressureCookerServer());
  64. devices.TryAdd(EDeviceType.外部设备, new OtherServer());
  65. morkCL.IsUseSplitStorage = Json<ConnectPar>.Data.IsUseSplitStorage;
  66. #if !FORMAL
  67. if (Json<ConnectPar>.Data.FryPanConnect_1)
  68. {
  69. devices[EDeviceType.炒锅1].Init(Json<ConnectPar>.Data.FryingPanIP1);
  70. }
  71. if (Json<ConnectPar>.Data.FryPanConnect_2)
  72. {
  73. devices[EDeviceType.炒锅2].Init(Json<ConnectPar>.Data.FryingPanIP2);
  74. }
  75. if (Json<ConnectPar>.Data.RobotConnet)
  76. {
  77. devices[EDeviceType.机器人].Init(Json<ConnectPar>.Data.RobotIP);
  78. }
  79. if (Json<ConnectPar>.Data.PressureCookerConnect)
  80. {
  81. devices[EDeviceType.压力锅].Init(Json<ConnectPar>.Data.PressureCookerIP);
  82. }
  83. if (Json<ConnectPar>.Data.OtherDeviceConnect)
  84. {
  85. devices[EDeviceType.外部设备].Init(PortName: Json<ConnectPar>.Data.ESPortName);
  86. }
  87. #endif
  88. ManualActionRegiester();
  89. }
  90. public override void MainTask()
  91. {
  92. //检查到有任务完成后将对已完成的任务进行清理
  93. var res = TaskList.FirstOrDefault(p => p.Value.IsComplete).Key;
  94. if (TaskList.ContainsKey(res))
  95. TaskList.TryRemove(res, out _);
  96. if (TaskList.IsEmpty)
  97. {
  98. morkCL.CanItemStorage = true;
  99. }
  100. else
  101. {
  102. morkCL.CanItemStorage = false;
  103. }
  104. //分配任务,这段程序必须写最后。
  105. if (morkCL.cds.Count > 0)
  106. {
  107. #region 修改为在下配方时选择使用哪个锅,这段程序不需要使用了。
  108. //var dishType = morkCL.cds.ElementAt(0).DishType;
  109. //var devieceType = EDeviceType.无;
  110. //if (dishType == Model.Recipe.EDishType.炒菜)
  111. //{
  112. // //如果任务队列里,炒锅1已经有任务了,就看炒锅2是否有任务,没任务就设置为炒锅2执行,如果两个锅都有任务则返回该次任务。
  113. // if (TaskList.ContainsKey(EDeviceType.炒锅1))
  114. // {
  115. // if (TaskList.ContainsKey(EDeviceType.炒锅2))
  116. // {
  117. // return;
  118. // }
  119. // else
  120. // { devieceType = EDeviceType.炒锅2; }
  121. // }
  122. // else
  123. // {
  124. // devieceType = EDeviceType.炒锅1;
  125. // }
  126. //}
  127. //else
  128. //{
  129. // devieceType = EDeviceType.压力锅;
  130. //}
  131. #endregion
  132. //这里判定主要是针对压力锅。
  133. //修改为炒锅和机器人不允许下单情况下,就不下单。
  134. if (!TaskList.ContainsKey(morkCL.cds.ElementAt(0).DeviceType)&&GetFryPanAndRobotIsAuto(morkCL.cds.ElementAt(0).DeviceType))
  135. {
  136. if (morkCL.cds.TryDequeue(out ControlData cd))
  137. {
  138. //cd.DeviceType = devieceType;
  139. //cd.DeviceType = EDeviceType.炒锅1;
  140. TaskList.TryAdd(cd.DeviceType, new TaskServer());
  141. TaskList[cd.DeviceType].TaskName = $"{cd.DeviceType.ToString()}-{cd.Name}";
  142. TaskList[cd.DeviceType].RunTask = new Task(new Action(() => { FryingPanControl(cd.DeviceType, cd); }));
  143. TaskList[cd.DeviceType].RunTask.Start();
  144. }
  145. }
  146. }
  147. }
  148. #region 日志修改前
  149. //private async void FryingPanControl(EDeviceType et, ControlData cd)
  150. //{
  151. // DeviceProcessLogShow($"【{et}】开始执行-{cd.Name} 任务");
  152. // if (TaskList.ContainsKey(et) && TaskList[et].Cts.IsCancellationRequested)
  153. // return;
  154. // while (cd.ControlFuncs.Count > 0)
  155. // {
  156. // if (cd.ControlFuncs.TryDequeue(out FuncModel fm))
  157. // {
  158. // var device = (FryingPanServer)devices[et];
  159. // var robot = (RobotServer)devices[EDeviceType.机器人];
  160. // var otherDevice = (OtherServer)devices[EDeviceType.外部设备];
  161. // int index = (ushort)et - 1;
  162. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}。");
  163. // switch (fm.eFunc)
  164. // {
  165. // case EFunc.搅拌启动:
  166. // device.StirStartOrStop = false;
  167. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入搅拌频率-{fm.funcPars.ElementAt(0).ParValue.ToString()}HZ。");
  168. // device.MixingFrequencySet(fm.funcPars.ElementAt(0).ParValue.ToString());
  169. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入搅拌频率-{fm.funcPars.ElementAt(0).ParValue.ToString()}HZ完成。");
  170. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入开始搅拌。");
  171. // device.StirStartOrStop = true;
  172. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入开始搅拌完成。");
  173. // break;
  174. // case EFunc.搅拌停止:
  175. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入停止搅拌。");
  176. // device.StirStartOrStop = false;
  177. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-写入停止搅拌完成。");
  178. // break;
  179. // case EFunc.加热启动:
  180. // device.HeatStartOrStop = false;
  181. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置加热挡位-【{fm.funcPars.ElementAt(0).ParValue.ToString()}】。");
  182. // device.HeatingGearSet(fm.funcPars.ElementAt(0).ParValue.ToString());
  183. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置加热挡位完成,设置加热启动。");
  184. // device.HeatStartOrStop = true;
  185. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置加热启动完成。");
  186. // break;
  187. // case EFunc.加热停止:
  188. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置加热停止。");
  189. // device.HeatStartOrStop = false;
  190. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置加热停止完成。");
  191. // break;
  192. // case EFunc.添加调料:
  193. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-查找调料【{fm.funcPars.ElementAt(0).Id}】。");
  194. // var Seasoning = SqliteHelper.GetInstance.GetSeasoning().FirstOrDefault(p => p.Id == fm.funcPars.ElementAt(0).Id);
  195. // if (Seasoning != null)
  196. // {
  197. // device.FryingPanToSeasoningLoc = false;
  198. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅到调料投料位置。");
  199. // device.FryingPanToSeasoningLoc = true;
  200. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅到调料投料位置完成。");
  201. // //回到投料位置就复位。
  202. // Thread.Sleep(50);
  203. // device.FeedingSeasoningLocFB.Wait(Cts: TaskList[et].Cts);
  204. // device.FryingPanToSeasoningLoc = false;
  205. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-炒锅已到达调料投料位置。");
  206. // device.CuttingControl(Seasoning.Loc.ToString(), fm.funcPars.ElementAt(1).ParValue.ToString());
  207. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-执行下料,下料位置:{Seasoning.Loc.ToString()},下料重量:【{fm.funcPars.ElementAt(1).ParValue.ToString()}】。");
  208. // }
  209. // else
  210. // {
  211. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-查找调料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】调料。任务取消。");
  212. // TaskList[et].Cts.Cancel();
  213. // }
  214. // break;
  215. // case EFunc.添加主料:
  216. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-查找主料【{fm.funcPars.ElementAt(0).Id}】。");
  217. // if (float.TryParse(fm.funcPars.ElementAt(1).ParValue.ToString(), out float weight))
  218. // {
  219. // //查找主料库位符合条件的物料库位,主要根据物料ID和物料重量查找。
  220. // var ingre_index = Array.FindIndex(Json<ItemStorageInfo>.Data.IngredientsStorage,
  221. // item => item.MaterialID == fm.funcPars.ElementAt(0).Id/* && item.Weight == weight*/);
  222. // if (ingre_index >= 0)
  223. // {
  224. // //device.CuttingControl(Seasoning.Loc.ToString(), fm.funcPars.ElementAt(1).ParValue.ToString());
  225. // var ingredientes = Json<ItemStorageInfo>.Data.IngredientsStorage[ingre_index];
  226. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-执行下料,控制取{ingre_index + 1}库物料,下料名称:{ingredientes.Name.ToString()},下料重量:【{fm.funcPars.ElementAt(1).ParValue.ToString()}】。");
  227. // device.FryingPanHome = false;
  228. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人任务【{(ingre_index + 1).ToString()}】,子任务【{et}】。");
  229. // robot.RobotTaskControl((ingre_index + 1).ToString(), et);
  230. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人任务【{(ingre_index + 1).ToString()}】,子任务【{et}】完成。");
  231. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回投料位置。");
  232. // device.FryingPanHome = true;
  233. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回投料位置完成。");
  234. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待炒锅到投料位置。");
  235. // device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);//等待炒锅到投料位置
  236. // device.FryingPanHome = false;
  237. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待炒锅到投料位置完成。");
  238. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待机器人到投料位置。");
  239. // robot.MaterialPouringRequest[index].Wait(Cts: TaskList[et].Cts); //等待机器人到投料位置也就是发出倒料请求。
  240. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待机器人到投料位置完成。");
  241. // //目前程序在炒锅在投料位置时,会自动发出允许倒料信息。
  242. // //DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置允许机器人开始投料。");
  243. // //robot.AllowPourVegetables(et);//允许机器人开始投料
  244. // //DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置允许机器人开始投料完成。");
  245. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-开始等待机器人投料完成。");
  246. // robot.MaterialPouringComplete[index].Wait(Cts: TaskList[et].Cts); //等待机器人投料完成
  247. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-机器人投料完成。");
  248. // Json<ItemStorageInfo>.Data.IngredientsStorage[ingre_index] = new ItemStorage();
  249. // Json<ItemStorageInfo>.Save();
  250. // ActionManage.GetInstance.Send("RefreshItemStorage");
  251. // }
  252. // else
  253. // {
  254. // //TODO:暂定为直接取消任务,后期再说。
  255. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-查找主料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】主料。任务取消。");
  256. // TaskList[et].Cts.Cancel();
  257. // }
  258. // }
  259. // break;
  260. // case EFunc.添加辅料:
  261. // MaterialBase mb = SqliteHelper.GetInstance.GetAccessories().FirstOrDefault(p => p.Id == fm.funcPars.ElementAt(0).Id);
  262. // if (mb != null)
  263. // {
  264. // //先复位变量。防止上一次是异常结束,设为True时,不会响应。
  265. // device.FryingPanHome = false;
  266. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人任务【{(mb.Loc + 12).ToString()}】,子任务【{et}】。");
  267. // robot.RobotTaskControl((mb.Loc + 12).ToString(), et);
  268. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人任务【{(mb.Loc + 12).ToString()}】,子任务【{et}】完成。");
  269. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回投料位置。");
  270. // device.FryingPanHome = true;
  271. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回投料位置完成。");
  272. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待炒锅到投料位置。");
  273. // device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);//等待炒锅到投料位置
  274. // device.FryingPanHome = false;
  275. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待炒锅到投料位置完成。");
  276. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待机器人到投料位置。");
  277. // robot.MaterialPouringRequest[index].Wait(Cts: TaskList[et].Cts); //等待机器人到投料位置
  278. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待机器人到投料位置完成。");
  279. // //DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置允许机器人开始投料。");
  280. // //robot.AllowPourVegetables(et);//允许机器人开始投料
  281. // //DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置允许机器人开始投料完成。");
  282. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-开始等待机器人投料完成。");
  283. // robot.MaterialPouringComplete[index].Wait(Cts: TaskList[et].Cts); //等待机器人投料完成
  284. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-机器人投料完成。");
  285. // }
  286. // else
  287. // {
  288. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-查找主料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】辅料。任务取消。");
  289. // TaskList[et].Cts.Cancel();
  290. // }
  291. // break;
  292. // case EFunc.炒锅回原点位:
  293. // device.FryingPanFeedingLoc = false;
  294. // device.FryingPanHome = false;
  295. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回原点。");
  296. // device.FryingPanHome = true;
  297. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅回原点完成。");
  298. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待回原点完成。");
  299. // device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);
  300. // device.FryingPanHome = false;
  301. // break;
  302. // case EFunc.出餐启动:
  303. // device.DiningOutStart = false;
  304. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人取空盆。");
  305. // //TODO:暂时修改,后期优化。
  306. // while (true)
  307. // {
  308. // var emptyPanIndex = Array.FindIndex(otherDevice.BoxDetection, i => i == true);
  309. // if (emptyPanIndex >= 0)
  310. // {
  311. // robot.RobotTaskControl((21 + emptyPanIndex).ToString(), et);//取空盆
  312. // break;
  313. // }
  314. // await Task.Delay(3000);
  315. // DeviceProcessLogShow("无空盆,请添加空盆!");
  316. // }
  317. // //robot.RobotTaskControl("21", et);//取空盆
  318. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置机器人取空盆完成,等待机器人到出菜位置。");
  319. // robot.DiningOutRequest[index].Wait(Cts: TaskList[et].Cts);//等待机器人到出菜位置
  320. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-机器人已到出餐位置,出餐启动。");
  321. // device.DiningOutStart = true;
  322. // device.OutDinningSlowDownFlag.Wait(Cts: TaskList[et].Cts);
  323. // robot.ModerateInPlace(et);
  324. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-到达出餐减速位。");
  325. // device.OutDinningFinsh.Wait(Cts: TaskList[et].Cts);
  326. // robot.DiningOutComplete(et);
  327. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-出餐完成。");
  328. // //回到投料位置就复位。
  329. // Thread.Sleep(50);
  330. // device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);
  331. // device.DiningOutStart = false;
  332. // break;
  333. // case EFunc.炒锅清洗:
  334. // device.FryingPanClear = false;
  335. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅清洗。");
  336. // device.FryingPanClear = true;
  337. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-炒锅清洗已写入。");
  338. // Thread.Sleep(500);
  339. // device.CleanFinish.Wait(Cts: TaskList[et].Cts);
  340. // device.FryingPanClear = false;
  341. // break;
  342. // case EFunc.炒锅回调料投料位置:
  343. // device.FryingPanToSeasoningLoc = false;
  344. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅到调料投料位置。");
  345. // device.FryingPanToSeasoningLoc = true;
  346. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置炒锅到调料投料位置完成。");
  347. // //回到投料位置就复位。
  348. // Thread.Sleep(50);
  349. // device.FeedingSeasoningLocFB.Wait(Cts: TaskList[et].Cts);
  350. // device.FryingPanToSeasoningLoc = false;
  351. // break;
  352. // case EFunc.去指定炒制位:
  353. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置去指定炒制位。");
  354. // device.SetStirFryingLoc(fm.funcPars.ElementAt(0).ParValue.ToString());
  355. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-设置去指定炒制位【{fm.funcPars.ElementAt(0).ParValue.ToString()}】完成。");
  356. // break;
  357. // case EFunc.炒制:
  358. // if (int.TryParse(fm.funcPars.ElementAt(0).ParValue.ToString(), out int time))
  359. // {
  360. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-等待炒制【{time}】秒。");
  361. // Task.Delay(time * 1000).Wait(TaskList[et].Cts.Token);
  362. // }
  363. // DeviceProcessLogShow($"{cd.Name}-任务执行-{fm.eFunc.ToString()}-炒制完成。");
  364. // break;
  365. // default:
  366. // break;
  367. // }
  368. // }
  369. // }
  370. // DeviceProcessLogShow($"【{et}】任务-{cd.Name} 执行完成");
  371. //}
  372. #endregion
  373. #region 炒锅流程控制日志修改后
  374. private async void FryingPanControl(EDeviceType et, ControlData cd)
  375. {
  376. DeviceProcessLogShow($"【{et}】开始执行-{cd.Name} 任务");
  377. if (TaskList.ContainsKey(et) && TaskList[et].Cts.IsCancellationRequested)
  378. return;
  379. while (cd.ControlFuncs.Count > 0 && !TaskList[et].Cts.IsCancellationRequested)
  380. {
  381. if (cd.ControlFuncs.TryDequeue(out FuncModel fm))
  382. {
  383. var device = (FryingPanServer)devices[et];
  384. var robot = (RobotServer)devices[EDeviceType.机器人];
  385. var otherDevice = (OtherServer)devices[EDeviceType.外部设备];
  386. int index = (ushort)et - 1;
  387. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}。");
  388. try
  389. {
  390. switch (fm.eFunc)
  391. {
  392. #region 搅拌启动与停止
  393. case EFunc.搅拌启动:
  394. device.StirStartOrStop = false;
  395. device.MixingFrequencySet(fm.funcPars.ElementAt(0).ParValue.ToString());
  396. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-写入搅拌频率-{fm.funcPars.ElementAt(0).ParValue.ToString()}HZ完成。");
  397. await Task.Delay(400);
  398. device.StirStartOrStop = true;
  399. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-写入开始搅拌完成。");
  400. break;
  401. case EFunc.搅拌停止:
  402. device.StirStartOrStop = false;
  403. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-写入停止搅拌完成。");
  404. break;
  405. #endregion
  406. #region 加热启动与停止
  407. case EFunc.加热启动:
  408. device.HeatStartOrStop = false;
  409. await Task.Delay(400);
  410. device.HeatingGearSet(fm.funcPars.ElementAt(0).ParValue.ToString());
  411. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置加热挡位-【{fm.funcPars.ElementAt(0).ParValue.ToString()}】完成,等待设置加热启动。");
  412. device.HeatStartOrStop = true;
  413. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置加热启动完成。");
  414. break;
  415. case EFunc.加热停止:
  416. device.HeatStartOrStop = false;
  417. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置加热停止完成。");
  418. break;
  419. #endregion
  420. #region 添加调料
  421. case EFunc.添加调料:
  422. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-查找调料【{fm.funcPars.ElementAt(0).Id}】。");
  423. var Seasoning = SqliteHelper.GetInstance.GetSeasoning().FirstOrDefault(p => p.Id == fm.funcPars.ElementAt(0).Id);
  424. if (Seasoning != null)
  425. {
  426. device.FryingPanToSeasoningLoc = false;
  427. await Task.Delay(400);
  428. device.FryingPanToSeasoningLoc = true;
  429. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置炒锅到调料投料位置完成,等待炒锅到达调料投料位置。");
  430. //回到投料位置就复位。
  431. await Task.Delay(400);
  432. device.FeedingSeasoningLocFB.Wait(Cts: TaskList[et].Cts);
  433. device.FryingPanToSeasoningLoc = false;
  434. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-炒锅已到达调料投料位置。");
  435. device.CuttingControl(Seasoning.Loc.ToString(), fm.funcPars.ElementAt(1).ParValue.ToString(), TaskList[et].Cts);
  436. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-执行下料,下料位置:{Seasoning.Loc.ToString()},下料重量:【{fm.funcPars.ElementAt(1).ParValue.ToString()}】。");
  437. //去炒制位
  438. string stirFryLoc = fm.funcPars.ElementAt(2).ParValue.ToString();
  439. GoStirFryLoc(stirFryLoc);
  440. //炒制
  441. if (int.TryParse(fm.funcPars.ElementAt(3).ParValue.ToString(), out int time1))
  442. {
  443. StirFry(time1);
  444. }
  445. }
  446. else
  447. {
  448. MessageNotify.GetInstance.ShowDialog($"任务【{cd.Name}】查找调料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】调料,任务即将取消。", DialogType.Warning);
  449. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-查找调料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】调料。任务取消。");
  450. TaskList[et].Cts.Cancel();
  451. }
  452. break;
  453. #endregion
  454. #region 添加主料
  455. case EFunc.添加主料:
  456. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-查找主料【{fm.funcPars.ElementAt(0).Id}】。");
  457. if (float.TryParse(fm.funcPars.ElementAt(1).ParValue.ToString(), out float weight))
  458. {
  459. robot.IsIdle.Wait(Cts: TaskList[et].Cts);
  460. //查找主料库位符合条件的物料库位,主要根据物料ID和物料重量查找。
  461. var ingre_index = Array.FindIndex(Json<ItemStorageInfo>.Data.IngredientsStorage,
  462. item => item.MaterialID == fm.funcPars.ElementAt(0).Id/* && item.Weight == weight*/);
  463. if (ingre_index >= 0)
  464. {
  465. var ingredientes = Json<ItemStorageInfo>.Data.IngredientsStorage[ingre_index];
  466. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-执行下料,控制取{ingre_index + 1}库物料,下料名称:{ingredientes.Name.ToString()},下料重量:【{fm.funcPars.ElementAt(1).ParValue.ToString()}】。");
  467. device.FryingPanHome = false;
  468. robot.RobotTaskControl((ingre_index + 1).ToString(), et);
  469. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置机器人任务【{(ingre_index + 1).ToString()}】,子任务【{et}】完成。");
  470. await Task.Delay(400);
  471. device.FryingPanHome = true;
  472. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置炒锅回投料位置完成,等待炒锅回到主料辅料投料位置");
  473. device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);//等待炒锅到投料位置
  474. await Task.Delay(400);
  475. device.FryingPanHome = false;
  476. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-等待炒锅到投料位置完成。");
  477. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-等待机器人到投料位置。");
  478. robot.MaterialPouringRequest[index].Wait(Cts: TaskList[et].Cts); //等待机器人到投料位置也就是发出倒料请求。
  479. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-机器人已到达投料位置,等待机器人投料完成。");
  480. robot.MaterialPouringComplete[index].Wait(Cts: TaskList[et].Cts); //等待机器人投料完成
  481. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-机器人投料完成。");
  482. Json<ItemStorageInfo>.Data.IngredientsStorage[ingre_index] = new ItemStorage();
  483. Json<ItemStorageInfo>.Save();
  484. ActionManage.GetInstance.Send("RefreshItemStorage");
  485. //去炒制位
  486. string stirFryLoc = fm.funcPars.ElementAt(2).ParValue.ToString();
  487. GoStirFryLoc(stirFryLoc);
  488. //炒制
  489. if (int.TryParse(fm.funcPars.ElementAt(3).ParValue.ToString(), out int time2))
  490. {
  491. StirFry(time2);
  492. }
  493. }
  494. else
  495. {
  496. MessageNotify.GetInstance.ShowDialog($"任务【{cd.Name}】查找主料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】主料,任务即将取消。", DialogType.Warning);
  497. //TODO:暂定为直接取消任务,后期再说。
  498. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-查找主料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】主料。任务取消。");
  499. TaskList[et].Cts.Cancel();
  500. }
  501. }
  502. break;
  503. #endregion
  504. #region 添加辅料
  505. case EFunc.添加辅料:
  506. #region 根据配置文件选择每个炒锅的最大最小辅料位置,暂时没使用。
  507. var minloc = 1;
  508. var maxloc = 8;
  509. if (morkCL.IsUseSplitStorage)
  510. {
  511. if (et == EDeviceType.炒锅1)
  512. {
  513. minloc = Json<ConnectPar>.Data.FryPanAccessoriesMin_1;
  514. maxloc = Json<ConnectPar>.Data.FryPanAccessoriesMax_1;
  515. }
  516. else if (et == EDeviceType.炒锅2)
  517. {
  518. minloc = Json<ConnectPar>.Data.FryPanAccessoriesMin_2;
  519. maxloc = Json<ConnectPar>.Data.FryPanAccessoriesMax_2;
  520. }
  521. }
  522. else
  523. {
  524. minloc = 1;
  525. maxloc = 8;
  526. }
  527. #endregion
  528. MaterialBase mb = SqliteHelper.GetInstance.GetAccessories().FirstOrDefault(p => p.Loc >= minloc && p.Loc <= maxloc && p.Id == fm.funcPars.ElementAt(0).Id);
  529. if (mb != null)
  530. {
  531. robot.IsIdle.Wait(Cts: TaskList[et].Cts);
  532. //先复位变量。防止上一次是异常结束,设为True时,不会响应。
  533. device.FryingPanHome = false;
  534. robot.RobotTaskControl((mb.Loc + 12).ToString(), et);
  535. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置机器人任务【{(mb.Loc + 12).ToString()}】,子任务【{et}】完成。");
  536. await Task.Delay(400);
  537. device.FryingPanHome = true;
  538. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置炒锅回投料位置完成,开始等待炒锅到投料位置。");
  539. device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);//等待炒锅到投料位置
  540. await Task.Delay(400);
  541. device.FryingPanHome = false;
  542. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-等待炒锅到投料位置完成,等待机器人到投料位置。");
  543. robot.MaterialPouringRequest[index].Wait(Cts: TaskList[et].Cts); //等待机器人到投料位置
  544. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-机器人到达投料位置完成,开始等待机器人投料完成。");
  545. robot.MaterialPouringComplete[index].Wait(Cts: TaskList[et].Cts); //等待机器人投料完成
  546. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-机器人投料完成。");
  547. //去炒制位
  548. string stirFryLoc = fm.funcPars.ElementAt(1).ParValue.ToString();
  549. GoStirFryLoc(stirFryLoc);
  550. //炒制
  551. if (int.TryParse(fm.funcPars.ElementAt(2).ParValue.ToString(), out int time3))
  552. {
  553. StirFry(time3);
  554. }
  555. }
  556. else
  557. {
  558. MessageNotify.GetInstance.ShowDialog($"任务【{cd.Name}】查找辅料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】辅料,任务即将取消。", DialogType.Warning);
  559. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-查找辅料失败,未查找到【{fm.funcPars.ElementAt(0).Id}】辅料。任务取消。");
  560. TaskList[et].Cts.Cancel();
  561. }
  562. break;
  563. #endregion
  564. case EFunc.炒锅回原点位:
  565. GoHome();
  566. break;
  567. #region 出餐启动
  568. case EFunc.出餐启动:
  569. device.DiningOutStart = false;
  570. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置机器人取空盆。");
  571. robot.IsIdle.Wait(Cts: TaskList[et].Cts);
  572. //TODO:暂时修改,后期优化。
  573. while (!TaskList[et].Cts.IsCancellationRequested)
  574. {
  575. var emptyPanIndex = Array.FindIndex(otherDevice.BoxDetection, i => i == true);
  576. if (emptyPanIndex >= 0)
  577. {
  578. robot.RobotTaskControl((21 + emptyPanIndex).ToString(), et);//取空盆
  579. break;
  580. }
  581. await Task.Delay(3000);
  582. DeviceProcessLogShow("无空盆,请添加空盆!");
  583. }
  584. //robot.RobotTaskControl("21", et);//取空盆
  585. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置机器人取空盆完成,等待机器人到出菜位置。");
  586. robot.DiningOutRequest[index].Wait(Cts: TaskList[et].Cts);//等待机器人到出菜位置
  587. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-机器人已到出餐位置,出餐启动。");
  588. await Task.Delay(400);
  589. device.DiningOutStart = true;
  590. device.OutDinningSlowDownFlag.Wait(Cts: TaskList[et].Cts);
  591. robot.ModerateInPlace(et);
  592. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-到达出餐减速位。");
  593. device.OutDinningFinsh.Wait(Cts: TaskList[et].Cts);
  594. robot.DiningOutComplete(et);
  595. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-出餐完成。");
  596. //回到投料位置就复位。
  597. Thread.Sleep(50);
  598. device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);
  599. await Task.Delay(400);
  600. device.DiningOutStart = false;
  601. break;
  602. #endregion
  603. #region 炒锅清洗--基本没用
  604. case EFunc.炒锅清洗:
  605. device.FryingPanClear = false;
  606. //DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置炒锅清洗。");
  607. await Task.Delay(400);
  608. device.FryingPanClear = true;
  609. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-炒锅清洗已写入,等待炒锅清洗完成。");
  610. Thread.Sleep(500);
  611. device.CleanFinish.Wait(Cts: TaskList[et].Cts);
  612. await Task.Delay(400);
  613. device.FryingPanClear = false;
  614. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-炒锅清洗完成。");
  615. break;
  616. #endregion
  617. #region
  618. case EFunc.去指定炒制位:
  619. //DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置去指定炒制位。");
  620. string loc = fm.funcPars.ElementAt(0).ParValue.ToString();
  621. GoStirFryLoc(loc);
  622. break;
  623. case EFunc.炒制:
  624. if (int.TryParse(fm.funcPars.ElementAt(0).ParValue.ToString(), out int time))
  625. {
  626. StirFry(time);
  627. }
  628. break;
  629. #endregion
  630. default:
  631. break;
  632. }
  633. #region 回原点
  634. void GoHome()
  635. {
  636. device.FryingPanFeedingLoc = false;
  637. device.FryingPanHome = false;
  638. //DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置炒锅回原点。");
  639. Task.Delay(400).Wait();
  640. device.FryingPanHome = true;
  641. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置炒锅回原点完成,等待炒锅回原点。");
  642. //DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-等待回原点完成。");
  643. device.FeedingLocFB.Wait(Cts: TaskList[et].Cts);
  644. Task.Delay(400).Wait();
  645. device.FryingPanHome = false;
  646. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-炒锅回原点完成。");
  647. }
  648. #endregion
  649. #region 去指定炒制位
  650. //去指定炒制位
  651. void GoStirFryLoc(string loc)
  652. {
  653. device.SetStirFryingLoc(loc, TaskList[et].Cts);
  654. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-设置去指定炒制位【{fm.funcPars.ElementAt(0).ParValue.ToString()}】完成。");
  655. //TODO:根据情况看是否需要等待反馈变量。
  656. //device.StirFryingLocFB[int.Parse(fm.funcPars.ElementAt(0).ParValue.ToString())].Wait();
  657. //DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-炒锅到达炒制位【{fm.funcPars.ElementAt(0).ParValue.ToString()}】。");
  658. }
  659. #endregion
  660. #region 炒制延时
  661. //炒制延时。
  662. void StirFry(int time)
  663. {
  664. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-等待炒制【{time}】秒。");
  665. Task.Delay(time * 1000).Wait(TaskList[et].Cts.Token);
  666. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务执行-{fm.eFunc.ToString()}-炒制完成。");
  667. }
  668. #endregion
  669. }
  670. catch (TaskCanceledException)
  671. {
  672. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务被取消。");
  673. }
  674. catch (OperationCanceledException)
  675. {
  676. DeviceProcessLogShow($"{cd.Name}-【{et}#】任务被手动取消。");
  677. }
  678. }
  679. }
  680. DeviceProcessLogShow($"【{et}】任务-{cd.Name} 执行完成");
  681. TaskList[et].IsComplete = true;
  682. }
  683. #endregion
  684. public override void ReadData()
  685. {
  686. if (propertyInfos is null || propertyInfos.Count==0)
  687. {
  688. propertyInfos = morkCL.GetType().GetProperties().ToList();
  689. }
  690. morkCL.RecipeQueueCount = morkCL.cds.Count;
  691. morkCL.FryingPanTaskCount_1 = morkCL.cds.Count(data => data.DeviceType == EDeviceType.炒锅1);
  692. morkCL.FryingPanTaskCount_2 = morkCL.cds.Count(data => data.DeviceType == EDeviceType.炒锅2);
  693. var fryingPan1 = (FryingPanServer)devices[EDeviceType.炒锅1];
  694. var fryingPan2 = (FryingPanServer)devices[EDeviceType.炒锅2];
  695. var robot = (RobotServer)devices[EDeviceType.机器人];
  696. var pressureCooker = (PressureCookerServer)devices[EDeviceType.压力锅];
  697. var otherDevice = (OtherServer)devices[EDeviceType.外部设备];
  698. alarm.EStop1 = fryingPan1.EStopAlarm;
  699. alarm.FryingPanFowardLimit1 = fryingPan1.FryingPanFowardLimit;
  700. alarm.FryingPanReverseLimit1 = fryingPan1.FryingPanReverseLimit;
  701. alarm.FryingPanEncoderCommError1 = fryingPan1.FryingPanEncoderCommError;
  702. alarm.StirMotorCommError1 = fryingPan1.StirMotorCommError;
  703. alarm.RollingMotorCommError1 = fryingPan1.RollingMotorCommError;
  704. alarm.StirMotorError1 = fryingPan1.StirMotorErrorCode != "无故障" ? true : false;
  705. alarm.TurnMotorError1 = fryingPan1.TurnMotorErrorCode != "无故障" ? true : false;
  706. alarm.EStop2 = fryingPan2.EStopAlarm;
  707. alarm.FryingPanFowardLimit2 = fryingPan2.FryingPanFowardLimit;
  708. alarm.FryingPanReverseLimit2 = fryingPan2.FryingPanReverseLimit;
  709. alarm.FryingPanEncoderCommError2 = fryingPan2.FryingPanEncoderCommError;
  710. alarm.StirMotorCommError2 = fryingPan2.StirMotorCommError;
  711. alarm.RollingMotorCommError2 = fryingPan2.RollingMotorCommError;
  712. alarm.StirMotorError2 = fryingPan2.StirMotorErrorCode != "无故障" ? true : false;
  713. alarm.TurnMotorError2 = fryingPan2.TurnMotorErrorCode != "无故障" ? true : false;
  714. //这是字段。直接赋值
  715. morkCL.FeedingSeasoningLocFB1 = fryingPan1.FeedingSeasoningLocFB;
  716. morkCL.FeedingSeasoningLocFB2 = fryingPan2.FeedingSeasoningLocFB;
  717. morkCL.FeedingLocFB1 = fryingPan1.FeedingLocFB;
  718. morkCL.FeedingLocFB2 = fryingPan2.FeedingLocFB;
  719. morkCL.CleanFinish1 = fryingPan1.CleanFinish;
  720. morkCL.CleanFinish2 = fryingPan2.CleanFinish;
  721. morkCL.OutDinningFinsh1 = fryingPan1.OutDinningFinsh;
  722. morkCL.OutDinningFinsh2 = fryingPan2.OutDinningFinsh;
  723. morkCL.OutDinningSlowDownFlag1 = fryingPan1.OutDinningSlowDownFlag;
  724. morkCL.OutDinningSlowDownFlag2 = fryingPan2.OutDinningSlowDownFlag;
  725. morkCL.BoxDetection = otherDevice.BoxDetection;
  726. morkCL.IsIdle = robot.IsIdle;
  727. #if !FORMAL
  728. if (fryingPan1.FeedingLocFB)
  729. {
  730. robot.AllowPourVegetables(EDeviceType.炒锅1);
  731. }
  732. else
  733. {
  734. robot.DisablePourVegetables(EDeviceType.炒锅1);
  735. }
  736. if (fryingPan2.FeedingLocFB)
  737. {
  738. robot.AllowPourVegetables(EDeviceType.炒锅2);
  739. }
  740. else
  741. {
  742. robot.DisablePourVegetables(EDeviceType.炒锅2);
  743. }
  744. foreach (var property in propertyInfos)
  745. {
  746. var att = property.GetCustomAttribute<VariableMonitorAttribute>();
  747. if (att != null)
  748. {
  749. if (att.Notes.Contains("1号炒锅"))
  750. {
  751. var p = fryingPan1.GetType().GetProperty(property.Name.TrimEnd('1'));
  752. if (p != null)
  753. {
  754. property.SetValue(morkCL, p.GetValue(fryingPan1));
  755. }
  756. }
  757. else if (att.Notes.Contains("2号炒锅"))
  758. {
  759. var p = fryingPan2.GetType().GetProperty(property.Name.TrimEnd('2'));
  760. if (p != null)
  761. {
  762. property.SetValue(morkCL, p.GetValue(fryingPan2));
  763. }
  764. }
  765. else if (att.Notes.Contains("机器人"))
  766. {
  767. var p = robot.GetType().GetProperty(property.Name);
  768. if (p != null)
  769. {
  770. property.SetValue(morkCL, p.GetValue(robot));
  771. }
  772. }
  773. else if (att.Notes.Contains("电子秤"))
  774. {
  775. var p = otherDevice.GetType().GetProperty(property.Name);
  776. if (p != null)
  777. {
  778. var res = p.GetValue(otherDevice);
  779. property.SetValue(morkCL, res);
  780. if (p.Name== "CurrentWeight")
  781. {
  782. ActionManage.GetInstance.Send("SendCurrentWeight", res);
  783. }
  784. }
  785. }
  786. else if (att.Notes.Contains("高压锅"))
  787. {
  788. var p = pressureCooker.GetType().GetProperty(property.Name);
  789. if (p != null)
  790. {
  791. property.SetValue(morkCL, p.GetValue(pressureCooker));
  792. }
  793. }
  794. }
  795. }
  796. #endif
  797. }
  798. public override void ResetProgram()
  799. {
  800. morkCL = null;
  801. morkCL = new GVL_MorkCL();
  802. }
  803. public override void SimOrder()
  804. {
  805. }
  806. public override void Stop()
  807. {
  808. }
  809. private bool GetFryPanAndRobotIsAuto(EDeviceType fryPan)
  810. {
  811. //目前拿不到机器人的远程状态,只能拿到炒锅的。
  812. var device = (FryingPanServer)devices[fryPan];
  813. var robot = (RobotServer)devices[EDeviceType.机器人];
  814. return device.InitComplete && device.StatusMode && device.EStop && robot.RemoteMode;
  815. }
  816. void ManualActionRegiester()
  817. {
  818. //主料入库委托。
  819. ActionManage.GetInstance.Register((object o) =>
  820. {
  821. if (!morkCL.CanItemStorage)
  822. {
  823. MessageNotify.GetInstance.ShowDialog("当前有炒菜任务正在排队,为避免影响菜品口味,不可入库,请稍后再试。", DialogType.Warning);
  824. NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "入库失败", $"物料入库失败,当前正在制作菜品。");
  825. return;
  826. }
  827. var robot = (RobotServer)devices[EDeviceType.机器人];
  828. if (robot.IsIdle==false)
  829. {
  830. MessageNotify.GetInstance.ShowDialog("当前机器人未在空闲状态,稍后再试。", DialogType.Warning);
  831. return;
  832. }
  833. TaskManage.GetInstance.Start(() =>
  834. {
  835. if (o != null && o is IngredientsTB ingredients)
  836. {
  837. var index = Array.FindIndex(Json<ItemStorageInfo>.Data.IngredientsStorage, i => i.IsEmploy == false);
  838. if (index >= 0)
  839. {
  840. if (!MessageNotify.GetInstance.ShowDialog($"请确认库位【{index+1}】上无物品,否则可能会造成碰撞事故!",DialogType.Warning))
  841. {
  842. DeviceProcessLogShow($"物料[{ingredients.Name}],ID:[{ingredients.Id}],库位[{index+1}]入库失败,未确认库位无异物。");
  843. Application.Current.Dispatcher.Invoke(() =>
  844. {
  845. NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "入库失败", $"物料{ingredients.Name}入库失败。");
  846. });
  847. return;
  848. }
  849. var item = Json<ItemStorageInfo>.Data.IngredientsStorage[index];
  850. item.MaterialID = ingredients.Id;
  851. item.Name = ingredients.Name;
  852. item.IsEmploy = true;
  853. item.Weight = ((OtherServer)devices[EDeviceType.外部设备]).CurrentWeight;
  854. var loc = (index + 1).ToString();
  855. #if !FORMAL
  856. robot.WarehousingControl(loc,null);
  857. DeviceProcessLogShow($"已下发机器人物料入{loc}号库任务,等待机器人入库操作完成");
  858. robot.WarehousingComplete[(Convert.ToInt32(loc) - 1)].Wait();
  859. #endif
  860. Json<ItemStorageInfo>.Save();
  861. ActionManage.GetInstance.Send("RefreshItemStorage");
  862. DeviceProcessLogShow($"物料[{ingredients.Name}],ID:[{ingredients.Id}],库位[{index + 1}]入库成功。");
  863. Application.Current.Dispatcher.Invoke(() =>
  864. {
  865. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, Application.Current.MainWindow, "入库成功", $"物料{ingredients.Name}入库成功。");
  866. });
  867. return;
  868. }
  869. else
  870. {
  871. Application.Current.Dispatcher.Invoke(() =>
  872. {
  873. NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "入库失败", $"物料库已满。");
  874. });
  875. }
  876. }
  877. else
  878. {
  879. Application.Current.Dispatcher.Invoke(() =>
  880. {
  881. NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "入库失败", $"物料入库失败。");
  882. });
  883. }
  884. }, "ItemStorageTask");
  885. }, NotifyTopic.ItemStorage, true);
  886. ActionManage.GetInstance.Register(() =>
  887. {
  888. if (ActionManage.GetInstance.SendResult("SystemIsBusy") is bool isBusy)
  889. {
  890. if (isBusy == true)
  891. {
  892. NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "失败", $"当前还有配方任务在排队制作,请稍后后再试。");
  893. return;
  894. }
  895. Task.Run(() =>
  896. {
  897. var robot = (RobotServer)devices[EDeviceType.机器人];
  898. robot.GoCleanLoc();
  899. Application.Current.Dispatcher.Invoke(() =>
  900. {
  901. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, Application.Current.MainWindow, "设置成功", $"设置机器人去清洗位置成功。");
  902. });
  903. robot.AtCleanLoc.Wait();
  904. Application.Current.Dispatcher.Invoke(() =>
  905. {
  906. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, Application.Current.MainWindow, "成功", $"机器人已到达清洗位置。");
  907. });
  908. });
  909. }
  910. }, "RobotGoCleanLoc", true);
  911. ActionManage.GetInstance.Register(() =>
  912. {
  913. Task.Run(() =>
  914. {
  915. var robot = (RobotServer)devices[EDeviceType.机器人];
  916. bool isSuccuess= robot.SendCleanFinish();
  917. if (isSuccuess)
  918. {
  919. Application.Current.Dispatcher.Invoke(() =>
  920. {
  921. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, Application.Current.MainWindow, "通知成功", $"通知机器人清洗完成成功。");
  922. });
  923. }
  924. });
  925. }, "RobotCleanFinish", true);
  926. #region 暂时弃用
  927. ActionManage.GetInstance.Register((object location) =>
  928. {
  929. var loc = location.ToString();
  930. if (!String.IsNullOrEmpty(loc) && loc.Length >= 0)
  931. {
  932. var robot = (RobotServer)devices[EDeviceType.机器人];
  933. //Thread.Sleep(5000);
  934. robot.WarehousingControl(loc,null);
  935. //会卡死。
  936. robot.WarehousingComplete[(Convert.ToInt32(loc) - 1)].Wait();
  937. }
  938. }, "ItemStorage", true);
  939. #endregion
  940. ActionManage.GetInstance.Register((object[] o) =>
  941. {
  942. if (o is not null && o is object[] para)
  943. {
  944. var device =(EDeviceType)Enum.Parse(typeof(EDeviceType), para[0].ToString());
  945. var channelIndex = para[1].ToString();
  946. var demandValue = para[2].ToString();
  947. ((FryingPanServer)devices[device]).CuttingControl(channelIndex, demandValue,null);
  948. }
  949. },"DeviceCuttingControl",true);
  950. ActionManage.GetInstance.Register((object o) =>
  951. {
  952. if (o is not null)
  953. {
  954. var device = (EDeviceType)Enum.Parse(typeof(EDeviceType), o.ToString());
  955. if (TaskList.ContainsKey(device))
  956. {
  957. TaskList[device].Cts.Cancel();
  958. DeviceProcessLogShow($"取消{device}当前任务成功。");
  959. }
  960. else
  961. {
  962. DeviceProcessLogShow($"[{device}]当前无任务。");
  963. }
  964. }
  965. }, "CancelFryPanTask", true);
  966. ActionManage.GetInstance.Register((object o) =>
  967. {
  968. if (o is not null)
  969. {
  970. var device = (EDeviceType)Enum.Parse(typeof(EDeviceType), o.ToString());
  971. //TODO : 把所有属于该炒锅的任务全部删除。
  972. }
  973. }, "ClearFryPanTask", true);
  974. ActionManage.GetInstance.Register(() =>
  975. {
  976. //电子秤去皮
  977. var weghier = (OtherServer)devices[EDeviceType.外部设备];
  978. if (weghier.WeigherTare())
  979. {
  980. Application.Current.Dispatcher.Invoke(() =>
  981. {
  982. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, Application.Current.MainWindow, "去皮成功", $"电子秤除皮操作成功。");
  983. });
  984. DeviceProcessLogShow($"电子秤除皮操作成功。");
  985. }
  986. else
  987. {
  988. Application.Current.Dispatcher.Invoke(() =>
  989. {
  990. NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "去皮失败", $"电子秤除皮操作失败。");
  991. });
  992. DeviceProcessLogShow($"电子秤除皮操作失败。");
  993. }
  994. },"WeighrTare",true);
  995. ActionManage.GetInstance.Register(() =>
  996. {
  997. //电子秤置零
  998. var weghier = (OtherServer)devices[EDeviceType.外部设备];
  999. if (weghier.WeigherZero())
  1000. {
  1001. Application.Current.Dispatcher.Invoke(() =>
  1002. {
  1003. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, Application.Current.MainWindow, "置零成功", $"电子秤置零操作成功。");
  1004. });
  1005. DeviceProcessLogShow($"电子秤置零操作成功。");
  1006. }
  1007. else
  1008. {
  1009. Application.Current.Dispatcher.Invoke(() =>
  1010. {
  1011. NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "置零失败", $"电子秤置零操作失败。");
  1012. });
  1013. DeviceProcessLogShow($"电子秤置零操作失败。");
  1014. }
  1015. }, "WeighrZero", true);
  1016. ActionManage.GetInstance.Register((object o) =>
  1017. {
  1018. if (o != null && o is WriteModel<bool> write)
  1019. {
  1020. if (!TaskList.ContainsKey(write.DeviceType))
  1021. {
  1022. devices[write.DeviceType].WriteValue<bool>(write.Address, write.Value);
  1023. DeviceProcessLogShow($"设备[{write.DeviceType}]--手动写入地址[{write.Address}],值[{write.Value}]");
  1024. }
  1025. }
  1026. }, "WriteBool", true);
  1027. ActionManage.GetInstance.Register((object o) =>
  1028. {
  1029. if (o != null && o is WriteModel<ushort> write)
  1030. {
  1031. if (!TaskList.ContainsKey(write.DeviceType))
  1032. {
  1033. devices[write.DeviceType].WriteValue<ushort>(write.Address, write.Value);
  1034. DeviceProcessLogShow($"设备[{write.DeviceType}]--手动写入地址[{write.Address}],值[{write.Value}]");
  1035. }
  1036. //else
  1037. //{
  1038. // //MessageNotify.GetInstance.ShowDialog("当前有炒菜任务,不可手动操作,请稍后再试。", DialogType.Warning);
  1039. // NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "操作失败", $"手动操作失败,当前正在制作菜品。");
  1040. // return;
  1041. //}
  1042. }
  1043. }, "WriteUshort", true);
  1044. ActionManage.GetInstance.Register(frypanIsIdle, "GetDeviceIsIdle", true);
  1045. ActionManage.GetInstance.Register(() =>
  1046. {
  1047. var robot = (RobotServer)devices[EDeviceType.机器人];
  1048. if (robot.InitVariable())
  1049. {
  1050. Application.Current.Dispatcher.Invoke(() => { NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, Application.Current.MainWindow, "成功", $"复位所有由上位机下发至机器人的变量成功。"); });
  1051. DeviceProcessLogShow($"复位所有由上位机下发至机器人的变量成功。");
  1052. }
  1053. else
  1054. {
  1055. Application.Current.Dispatcher.Invoke(() => { NoticeDemoViewModel.OpenMsg(EnumPromptType.Error, Application.Current.MainWindow, "失败", $"复位所有由上位机下发至机器人的变量失败。"); });
  1056. DeviceProcessLogShow($"复位所有由上位机下发至机器人的变量失败。");
  1057. }
  1058. }, "InitRobotAllVar", true);
  1059. ActionManage.GetInstance.Register<Func<object>>(() =>
  1060. {
  1061. if (morkCL.RecipeQueueCount > 0 || morkCL.FryingPanTaskCount_1 > 0 || morkCL.FryingPanTaskCount_2 > 0)
  1062. {
  1063. return true;
  1064. }
  1065. return false;
  1066. },"SystemIsBusy",true);
  1067. }
  1068. Func<object, object> frypanIsIdle => (o) =>
  1069. {
  1070. if (o is not null)
  1071. {
  1072. var device = (EDeviceType)Enum.Parse(typeof(EDeviceType), o.ToString());
  1073. if (!TaskList.ContainsKey(device))
  1074. {
  1075. return true;
  1076. }
  1077. }
  1078. return false;
  1079. };
  1080. }
  1081. }