终端一体化运控平台
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.
 
 
 

661 regels
35 KiB

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