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

854 lines
46 KiB

  1. //#define Debug
  2. extern alias aliyun;
  3. using BPA.Helper;
  4. using BPASmartClient.CustomResource.Pages.Model;
  5. using BPASmartClient.CustomResource.UserControls;
  6. using BPASmartClient.CustomResource.UserControls.MessageShow;
  7. using BPASmartClient.DosingSystem.ViewModel;
  8. using BPASmartClient.Model;
  9. using System;
  10. using System.Collections.Concurrent;
  11. using System.Collections.ObjectModel;
  12. using System.Collections.Specialized;
  13. using System.Diagnostics;
  14. using System.Linq;
  15. using System.Threading;
  16. using System.Threading.Tasks;
  17. using aliyun.uPLibrary.Networking.M2Mqtt.Messages;
  18. using System.Collections.Generic;
  19. using aliyun::BPA.PahoMQ;
  20. using System.Configuration;
  21. using BPA.Communication;
  22. using Newtonsoft.Json;
  23. using System.Reflection;
  24. using System.Text;
  25. using BPASmartClient.DosingSystem.Model;
  26. using Microsoft.EntityFrameworkCore.Metadata.Internal;
  27. using System.Collections;
  28. using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
  29. using System.Windows.Navigation;
  30. using System.Text.RegularExpressions;
  31. using static System.Resources.ResXFileRef;
  32. using BPASmartClient.DosingSystem.Model.Dto;
  33. using BPASmartClient.DosingSystem.Model.MQTT;
  34. using Microsoft.VisualBasic.Logging;
  35. using Org.BouncyCastle.Asn1.Utilities;
  36. using Google.Protobuf.WellKnownTypes;
  37. using System.Windows;
  38. using System.Windows.Media.Converters;
  39. using SqlSugar;
  40. using Microsoft.VisualBasic;
  41. namespace BPASmartClient.DosingSystem
  42. {
  43. /// <summary>
  44. /// 业务逻辑执行类
  45. /// </summary>
  46. public class ExcuteControl
  47. {
  48. private static ExcuteControl Instance;
  49. public static ExcuteControl GetInstance => Instance ??= new ExcuteControl();
  50. public ConcurrentDictionary<string, aliyun.BPA.PahoMQ.MessageHandler> mqttCollection = new ConcurrentDictionary<string, aliyun.BPA.PahoMQ.MessageHandler>();
  51. public ConcurrentDictionary<string, string> aliyun = new ConcurrentDictionary<string, string>();
  52. public ObservableCollection<RecipeModel> Recipes { get; set; } = Json<LocalRecipe>.Data.Recipes;
  53. public ObservableCollection<StockStatusModel> StockStatus = new ObservableCollection<StockStatusModel>();
  54. public Action Raction { get; set; }
  55. public string CurrentRecipeName { get; set; }
  56. /// <summary>
  57. /// 当前正在制作的配方
  58. /// </summary>
  59. public ObservableCollection<RecipeModel> recipeProcesses { get; set; } = new ObservableCollection<RecipeModel>();
  60. /// <summary>
  61. /// 等待制作的配方
  62. /// </summary>
  63. public ObservableCollection<RecipeModel> UserTreeWait { get; set; } = new ObservableCollection<RecipeModel>();
  64. /// <summary>
  65. /// 已完成的配方
  66. /// </summary>
  67. public ObservableCollection<RecipeModel> UserTreeCompelete { get; set; } = new ObservableCollection<RecipeModel>();
  68. public ConcurrentQueue<string> RecipeNames = new ConcurrentQueue<string>();
  69. /// <summary>
  70. /// 配料完成计数
  71. /// </summary>
  72. int Comcount = 0;
  73. public static bool PropertySet = false;//云端属性设置回调主题订阅标志
  74. public static bool PropertyReport = false; //属性上报主题订阅标志
  75. public static bool EventReport = false; //事件上报主题订阅标志
  76. public static bool ServiceCall = false;//服务调用回调主题订阅标志
  77. public NameValueCollection produtInfo;
  78. public NameValueCollection mqttInfo;
  79. public NameValueCollection ConveyerInfo;
  80. public NameValueCollection ServicesInfo;
  81. public bool AliyunIsConnect = false;
  82. public ExcuteControl()
  83. {
  84. ActionManage.GetInstance.Register<object>(new Action<object>((o) =>
  85. {
  86. if (o != null && o is string recipeName)
  87. {
  88. RecipeSend(recipeName);
  89. }
  90. }), "配方下发");
  91. ActionManage.GetInstance.Register<object>(new Action<object>((ob) =>
  92. {
  93. if (ob != null && ob is string recipeName)
  94. {
  95. CancelRecipe(recipeName);
  96. }
  97. }), "取消配方");
  98. //AliYunInit();
  99. //RecipeRun();
  100. //BusinessExcute();
  101. MatchRun();
  102. //ConveyerPropertyReport();
  103. //ThreadTaskInit();
  104. #if Debug
  105. Task.Run(() => {
  106. while (true)
  107. {
  108. if (AliyunIsConnect)
  109. {
  110. for (int i = 0; i < 6; i++)
  111. {
  112. AliyunEventReport($"192.168.0.{i+1}0", new AliyunStockEventReportModel { Result = "1" }, "StockJerk1StatusEvent", AliyunMaterialModelType.StockModel);
  113. AliyunEventReport($"192.168.0.{i + 1}0", new AliyunStockEventReportModel { Result = "1" }, "StockServoFalutEvent", AliyunMaterialModelType.StockModel);
  114. AliyunEventReport($"192.168.0.{i + 1}0", new AliyunStockEventReportModel { Result = "1" }, "StockJerk2StatusEvent", AliyunMaterialModelType.StockModel);
  115. AliyunEventReport($"192.168.0.{i + 1}0", new AliyunStockEventReportModel { Result = "1" }, "StockUpLimitEvent", AliyunMaterialModelType.StockModel);
  116. AliyunEventReport($"192.168.0.{i + 1}0", new AliyunStockEventReportModel { Result = "1" }, "StockDownLimitEvent", AliyunMaterialModelType.StockModel);
  117. AliyunStockPropertyReportModel model = new AliyunStockPropertyReportModel();
  118. model.StockRealWeight = 1;
  119. model.BucketRealWeight = 2;
  120. model.StockDeviceNum = 2;
  121. model.StockDeviceName = "测试";
  122. model.StockWorkModel = 0;
  123. model.StockSlowlyAddWeight = 6;
  124. model.StockPreCloseValueWeight = 7;
  125. model.StockRapidAcceleration = 46;
  126. model.StockSlowAcceleration = 24;
  127. model.StockServoManualSpeed = 35;
  128. model.StockUpperLimitWeight = 57;
  129. model.StockLowerLimitWeight = 34;
  130. model.StockStirringSpeed = 54;
  131. model.StockMaterialType = "粉体";
  132. model.StockBatchStatus = "待机";
  133. StokcPropertyReport($"192.168.0.{i + 1}0", model);
  134. }
  135. AliyunConveyerPropertyReportModel model1 = new AliyunConveyerPropertyReportModel();
  136. model1.TopBucketControlStatus = 1;
  137. model1.DownBucketControlStatus =1;
  138. model1.RunStatus = 1;
  139. model1.WorkModel = 1;
  140. model1.TopBucketSigleCheck = 1;
  141. model1.ButtonBucketSigleCheck = 1;
  142. model1.ConveyerOnlineStatus =1;
  143. var mqdeviceTestProperty = new PostPropertyParams<AliyunConveyerPropertyReportModel>();
  144. mqdeviceTestProperty.sys = new Sys { ack = 1 };
  145. mqdeviceTestProperty.method = "thing.event.property.post";
  146. mqdeviceTestProperty.version = "1.0";
  147. mqdeviceTestProperty.ModelName = $"{produtInfo.Get("Conveyer")}";
  148. mqdeviceTestProperty.Model = model1;
  149. mqdeviceTestProperty.Init();
  150. var message = JsonConvert.SerializeObject(mqdeviceTestProperty);
  151. var topic = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/property/post";//发布主题
  152. var topicReply = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/property/post_reply";//订阅主题
  153. if (mqttCollection.ContainsKey("Conveyer"))
  154. {
  155. try
  156. {
  157. mqttCollection["Conveyer"].Publish((op) =>
  158. {
  159. op.Message = message;
  160. op.Topic = topic;
  161. op.TopicReply = topicReply;
  162. //if (!PropertyReport)
  163. //{
  164. // op.ThresholdCallback += MqttPostProperty_MqttMsgPublishReceived; // MqttPostProperty_MqttMsgPublishReceived;
  165. // PropertyReport = true;
  166. //}
  167. });
  168. }
  169. catch (Exception)
  170. {
  171. //throw;
  172. }
  173. }
  174. SystemEventReport("ProcessRecipe", new { RecipeName = "测试5" });//正在执行配方上报
  175. if (UserTreeWait.Count > 0)
  176. {
  177. string[] recipeNames = new string[UserTreeWait.Count];
  178. for (int i = 0; i < recipeNames.Length; i++)
  179. {
  180. recipeNames[i] = UserTreeWait.ElementAt(i).RecipeName;
  181. }
  182. SystemEventReport("WaitProcessRecipe", new { RecipeNames = recipeNames });//等待执行配方上报
  183. }
  184. else
  185. {
  186. SystemEventReport("WaitProcessRecipe", new { RecipeNames = new string[] { } });//等待执行配方上报
  187. }
  188. }
  189. Thread.Sleep(5000);
  190. }
  191. });
  192. #endif
  193. }
  194. /// <summary>
  195. /// 料仓属性上报
  196. /// </summary>
  197. /// <param name="ipaddres"></param>
  198. /// <param name="model"></param>
  199. public void StokcPropertyReport<T>(string ipaddres, T model)
  200. {
  201. var mqdeviceTestProperty = new PostPropertyParams<T>();
  202. mqdeviceTestProperty.sys = new Sys { ack = 1 };
  203. mqdeviceTestProperty.method = "thing.event.property.post";
  204. mqdeviceTestProperty.version = "1.0";
  205. mqdeviceTestProperty.ModelName = $"{produtInfo.Get("Stock")}";
  206. mqdeviceTestProperty.Model = model;
  207. mqdeviceTestProperty.Init();
  208. var message = JsonConvert.SerializeObject(mqdeviceTestProperty);
  209. var topic = $"/sys/{produtInfo.Get("ProductKey")}/{aliyun[ipaddres]}/thing/event/property/post";//发布主题
  210. var topicReply = $"/sys/{produtInfo.Get("ProductKey")}/{aliyun[ipaddres]}/thing/event/property/post_reply";//订阅主题
  211. if (mqttCollection.ContainsKey(aliyun[ipaddres]))
  212. {
  213. try
  214. {
  215. mqttCollection[aliyun[ipaddres]].Publish((op) =>
  216. {
  217. op.Message = message;
  218. op.Topic = topic;
  219. op.TopicReply = topicReply;
  220. //if (!PropertyReport)
  221. //{
  222. // op.ThresholdCallback += MqttPostProperty_MqttMsgPublishReceived; // MqttPostProperty_MqttMsgPublishReceived;
  223. // PropertyReport = true;
  224. //}
  225. });
  226. }
  227. catch (Exception)
  228. {
  229. //throw;
  230. }
  231. }
  232. }
  233. /// <summary>
  234. /// 业务系统属性上报
  235. /// </summary>
  236. public void SystemPropertyReport<T>(T model)
  237. {
  238. var mqdeviceTestProperty = new PostPropertyParams<T>();
  239. mqdeviceTestProperty.sys = new Sys { ack = 1 };
  240. mqdeviceTestProperty.method = "thing.event.property.post";
  241. mqdeviceTestProperty.version = "1.0";
  242. mqdeviceTestProperty.Model = model;
  243. mqdeviceTestProperty.Init();
  244. var message = JsonConvert.SerializeObject(mqdeviceTestProperty);
  245. var topic = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/property/post";//发布主题
  246. var topicReply = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/property/post_reply";//订阅主题
  247. if (mqttCollection.ContainsKey("Conveyer"))
  248. {
  249. try
  250. {
  251. mqttCollection["Conveyer"].Publish((op) =>
  252. {
  253. op.Message = message;
  254. op.Topic = topic;
  255. op.TopicReply = topicReply;
  256. //if (!PropertyReport)
  257. //{
  258. // op.ThresholdCallback += MqttPostProperty_MqttMsgPublishReceived; // MqttPostProperty_MqttMsgPublishReceived;
  259. // PropertyReport = true;
  260. //}
  261. });
  262. }
  263. catch (Exception)
  264. {
  265. //throw;
  266. }
  267. }
  268. }
  269. /// <summary>
  270. /// 取消配方
  271. /// </summary>
  272. /// <param name="RecipeName"></param>
  273. public async void CancelRecipe(string RecipeName)
  274. {
  275. if (RecipeName != null)
  276. {
  277. //var res = MessageNotify.GetInstance.ShowDialog($"是否取消配方 【{RecipeName}】制作", DialogType.Warning);
  278. //if (res)
  279. //{
  280. int index = Recipes.ToList().FindIndex(p => p.RecipeName == RecipeName);
  281. if (index >= 0 && index < Recipes.Count)
  282. {
  283. await Task.Factory.StartNew(new Action(() =>
  284. {
  285. Recipes.ElementAt(index).IsEnable = true;
  286. Json<LocalRecipe>.Data.Recipes.ElementAt(index).IsEnable = true;
  287. Recipes.ElementAt(index).Are.Set();
  288. App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); }));
  289. //SiemensDevice.GetInstance.MySiemens.Write("M10.5", true);
  290. //MessageNotify.GetInstance.ShowRunLog($"M10.5:true");
  291. Thread.Sleep(1000);
  292. //SiemensDevice.GetInstance.MySiemens.Write("M10.5", false);
  293. //MessageNotify.GetInstance.ShowRunLog($"M10.5:false");
  294. App.Current.Dispatcher.Invoke(() =>
  295. {
  296. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方 [{RecipeName}] 取消成功");
  297. });
  298. MessageNotify.GetInstance.ShowUserLog($"取消配方制作 {RecipeName}");
  299. //取消成功
  300. }));
  301. }
  302. else
  303. {
  304. //取消失败
  305. }
  306. //}
  307. }
  308. else
  309. {
  310. MessageNotify.GetInstance.ShowUserLog($"配方 {RecipeName}取消失败");
  311. }
  312. }
  313. /// <summary>
  314. /// 配方下发
  315. /// </summary>
  316. public void RecipeSend(string RecipeName)
  317. {
  318. if (RecipeName != null)
  319. {
  320. int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == RecipeName);
  321. if (index >= 0 && index < Recipes.Count)
  322. {
  323. for (int i = 0; i < Recipes.ElementAt(index).RawMaterials.Count; i++)
  324. {
  325. string ip = Recipes.ElementAt(index).RawMaterials.ElementAt(i).DeviceIp;
  326. var device = DeviceInquire.GetInstance.GetDevice(ip);
  327. if (!device.IsConnected)
  328. {
  329. MessageNotify.GetInstance.ShowDialog($"设备 【{device.DeviceName}】 未连接,不允许下发此配方", DialogType.Error);
  330. return;
  331. }
  332. if (Recipes.ElementAt(index).RawMaterials.ElementAt(i).RawMaterialSource == 1)
  333. {
  334. if (ip == null && ip == "")
  335. {
  336. MessageNotify.GetInstance.ShowDialog($"原料 【{Recipes.ElementAt(index).RawMaterials.ElementAt(i).RawMaterialName}】配料系统无法配料,请人工配置此原料:原料{Recipes.ElementAt(index).RawMaterials.ElementAt(i).RawMaterialName},重量{Recipes.ElementAt(index).RawMaterials.ElementAt(i).RawMaterialWeight}", DialogType.Information);
  337. return;
  338. }
  339. }
  340. }
  341. Recipes.ElementAt(index).IsEnable = false;
  342. Json<LocalRecipe>.Data.Recipes.ElementAt(index).IsEnable = false;
  343. }
  344. MessageNotify.GetInstance.ShowUserLog($"下发工单 {Recipes.ElementAt(index).RecipeName}");
  345. RecipeNames.Enqueue(RecipeName);
  346. var res = Recipes.FirstOrDefault(p => p.RecipeName == RecipeName);
  347. App.Current.Dispatcher.Invoke(() =>
  348. {
  349. var raw = new ObservableCollection<RawMaterialModel>();
  350. res.RawMaterials.ToList().ForEach(X =>
  351. {
  352. raw.Add(new RawMaterialModel()
  353. {
  354. DeviceIp = X.DeviceIp,
  355. DownLimtFeedback = X.DownLimtFeedback,
  356. Loc= X.Loc,
  357. RawMaterialId = X.RawMaterialId,
  358. RawMaterialName = X.RawMaterialName,
  359. RawMaterialWeight = X.RawMaterialWeight,
  360. RecipeStatus = 1,
  361. TotalWeight = X.TotalWeight,
  362. Status = 0
  363. });
  364. });
  365. int count = RecipeNames.Count(p=>p == RecipeName);
  366. UserTreeWait.Add(new RecipeModel { RecipStatus = "等待制作", SerialNum = count, RecipeName = RecipeName, RawMaterials = raw });
  367. send = true;
  368. });
  369. }
  370. }
  371. public ConcurrentDictionary<string, int> doDeviceCount = new ConcurrentDictionary<string, int>();
  372. int dd = 0;
  373. public void ShutDownHandler()
  374. {
  375. TaskManage.GetInstance.StopTask("设备下发配方");
  376. TaskManage.GetInstance.StopTask("下发设备参数");
  377. TaskManage.GetInstance.StopTask("控制传送带");
  378. List<Task> tasks = new();
  379. tasks.Add(SimensSend.GetInstance.SendSimens.WriteAsync("M0.0", false));
  380. tasks.Add(SimensSend.GetInstance.SendSimens.WriteAsync("M0.1", false));
  381. /* foreach (var item in DeviceInquire.GetInstance.DeviceLists.Values)
  382. {
  383. tasks.Add( item.modbusTcp.WriteAsync<ushort>(DeviceAddress.TranspportSwitch.ToAdd(), 0));
  384. }
  385. Task.WaitAll(tasks.ToArray(),TimeSpan.FromSeconds(5));*/
  386. }
  387. public void ShutDown()
  388. {
  389. TaskManage.GetInstance.StopTask("设备下发配方");
  390. TaskManage.GetInstance.StopTask("配料机设备上线监听");
  391. TaskManage.GetInstance.StopTask("起始传送带控制");
  392. List<Task> tasks = new();
  393. tasks.Add(SimensSend.GetInstance.SendSimens.WriteAsync("M0.0", false));
  394. tasks.Add(SimensSend.GetInstance.SendSimens.WriteAsync("M0.1", false));
  395. tasks.Add(new Task(() =>
  396. {
  397. if (DeviceInquire.GetInstance.devices.Count==18)
  398. {
  399. Parallel.ForEach(DeviceInquire.GetInstance.devices, item =>
  400. {
  401. DeviceInquire.GetInstance.DeviceLists[item.IpAddress].ResetAll().Wait();
  402. });
  403. }
  404. }));
  405. Task.WaitAll(tasks.ToArray(), TimeSpan.FromSeconds(5));
  406. }
  407. bool send = false;
  408. public ConcurrentDictionary<string, bool> recipeSend = new ConcurrentDictionary<string, bool>();
  409. bool stop = true;
  410. bool start_Send = false;
  411. bool allowStart=false;
  412. public ConcurrentDictionary<string, bool> start_Stop = new ConcurrentDictionary<string, bool>();
  413. int pas = 1;
  414. private void MatchRun()
  415. {
  416. recipeProcesses.Clear();
  417. TaskManage.GetInstance.StartLong(() =>
  418. {
  419. if (RecipeNames.Count > 0 && SimensSend.GetInstance.IsConnect)
  420. {
  421. //下发设备参数
  422. //遍历每一个味魔方。
  423. for (int i = 0; i < DeviceInquire.GetInstance.devices.Count; i++)
  424. {
  425. //判断IP是否在列表中
  426. if (DeviceInquire.GetInstance.DeviceLists.ContainsKey(DeviceInquire.GetInstance.devices[i].IpAddress))
  427. {
  428. string ip = DeviceInquire.GetInstance.devices[i].IpAddress;
  429. if (!recipeSend.ContainsKey(ip))
  430. {
  431. recipeSend.TryAdd(ip, false);
  432. }
  433. if (doDeviceCount.ContainsKey(ip)&& recipeSend.ContainsKey(ip))
  434. {
  435. if (send)
  436. {
  437. recipeSend.ToList().ForEach(o =>
  438. {
  439. recipeSend.TryUpdate(o.Key, true, false);
  440. });
  441. send = false;
  442. }
  443. int index = 0;//配方索引
  444. int maxPail = 0;//最大桶数
  445. List<int> device_Loc = new List<int>();//下发桶号
  446. int recipeNameNum = doDeviceCount[ip];//配方数量
  447. int recipNameNum_1 = 0;//配方数量
  448. var dnum = DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.DeviceNum;//设备编号
  449. int passPail = DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.PassPail;//当前通过桶数
  450. int passPail_1 = -1;//下一料仓桶数
  451. string nextIp = "";
  452. if (dnum < 18)
  453. {
  454. nextIp = $"192.168.2.{(dnum + 1) * 10}";
  455. if (DeviceInquire.GetInstance.DeviceLists.ContainsKey(nextIp))
  456. {
  457. passPail_1 = DeviceInquire.GetInstance.DeviceLists[nextIp].deviceStatus.PassPail;
  458. recipNameNum_1 = doDeviceCount[nextIp];
  459. }
  460. }
  461. else
  462. {
  463. passPail_1 = passPail - 1;
  464. recipNameNum_1 = doDeviceCount["192.168.2.170"]-1;
  465. }
  466. if (recipeNameNum == 0)
  467. {
  468. recipeSend.TryUpdate(ip, false, true);
  469. index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == RecipeNames.ElementAt(recipeNameNum));
  470. if (index >= 0 && dnum > 0)
  471. {
  472. foreach (var rawMaterial in Recipes.ElementAt(index).RawMaterials)
  473. {
  474. if (rawMaterial.Loc > maxPail)
  475. {
  476. maxPail = rawMaterial.Loc;
  477. }
  478. if (rawMaterial.DeviceIp == DeviceInquire.GetInstance.devices[i].IpAddress)
  479. {
  480. device_Loc.Add(rawMaterial.Loc);
  481. }
  482. }
  483. if (passPail == 0)
  484. {
  485. doDeviceCount.TryUpdate(ip, recipeNameNum + 1, doDeviceCount[ip]);
  486. foreach (var down_Loc in device_Loc)
  487. {
  488. SimensSend.GetInstance.SendSimens.Write<bool>($"DB1.DBX{710 + 4 * (dnum - 1) + (int)((down_Loc - 1) / 8)}.{(down_Loc - 1) % 8}", true);
  489. }
  490. SimensSend.GetInstance.SendSimens.Write<ushort>($"DB1.DBW{106 + 2 * (dnum - 1)}", 500);//电机速度
  491. MessageNotify.GetInstance.ShowRunLog($"设备{dnum}下发配方{RecipeNames.ElementAt(recipeNameNum)}");
  492. if (dnum == 1)
  493. {
  494. App.Current.Dispatcher.Invoke(() =>
  495. {
  496. if (recipeNameNum >= 0 && recipeNameNum < RecipeNames.Count)
  497. {
  498. RecipeModel recipe = UserTreeWait.ToList().Find(a => a.RecipeName == RecipeNames.ElementAt(recipeNameNum));
  499. if (recipe != null)
  500. {
  501. recipe.RecipStatus = "正在配料";
  502. recipeProcesses.Insert(0, recipe);
  503. ActionManage.GetInstance.Send("正在配料", recipeProcesses);
  504. /*Json<OnRecipe>.Data.Recipes.Insert(0, recipe);
  505. Json<OnRecipe>.Save();*/
  506. int removeObj = UserTreeWait.ToList().FindIndex(a => a.RecipeName == RecipeNames.ElementAt(recipeNameNum));
  507. if (removeObj >= 0 && removeObj < UserTreeWait.Count())
  508. {
  509. UserTreeWait.RemoveAt(removeObj);
  510. }
  511. }
  512. }
  513. });
  514. }
  515. }
  516. }
  517. }
  518. bool pailAv = DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.PailArrive;
  519. if (recipeNameNum > 0 && recipeNameNum <= RecipeNames.Count&&!pailAv)
  520. {
  521. index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == RecipeNames.ElementAt(recipeNameNum - 1));
  522. if (index >= 0 && dnum > 0)
  523. {
  524. foreach (var rawMaterial in Recipes.ElementAt(index).RawMaterials)
  525. {
  526. if (rawMaterial.Loc > maxPail)
  527. {
  528. maxPail = rawMaterial.Loc;
  529. }
  530. }
  531. int recipecount = recipeProcesses.Count - (recipeNameNum - UserTreeCompelete.Count);
  532. int re = 0;
  533. /*if (recipeNameNum - (UserTreeCompelete.Count + recipeProcesses.Count) == 0)
  534. {
  535. re = -1;
  536. recipNameNum_1 = recipeNameNum;
  537. }*/
  538. if (recipecount < recipeProcesses.Count && recipecount >= 0)
  539. {
  540. re = recipeProcesses.ElementAt(recipecount).RawMaterials.ToList().FindIndex(a => a.RawMaterialName == DeviceInquire.GetInstance.DeviceLists[ip].DeviceName && a.Loc == DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.PassPail && a.RecipeStatus != 3);
  541. }
  542. else
  543. {
  544. re = -1;
  545. recipNameNum_1 = recipeNameNum;
  546. }
  547. if (recipeSend[ip])
  548. {
  549. if (re<0)
  550. {
  551. re = -1;
  552. recipNameNum_1 = recipeNameNum;
  553. }
  554. }
  555. if (dnum == 18 && maxPail <= passPail)
  556. {
  557. App.Current.Dispatcher.Invoke(() =>
  558. {
  559. if (recipecount < recipeProcesses.Count && recipecount >= 0)
  560. {
  561. RecipeModel recipe = recipeProcesses.ElementAt(recipecount);
  562. if (recipe != null)
  563. {
  564. int res = recipe.RawMaterials.ToList().FindIndex(a => a.RecipeStatus != 3);
  565. if (res < 0)
  566. {
  567. recipe.RecipStatus = "制作完成";
  568. UserTreeCompelete.Insert(0, recipe);
  569. recipeProcesses.RemoveAt(recipecount);
  570. Json<OnRecipe>.Data.Recipes = recipeProcesses;
  571. Json<OnRecipe>.Save();
  572. Json<OldRecipe>.Data.Recipes.Insert(0, recipe);
  573. Json<OldRecipe>.Save();
  574. ActionManage.GetInstance.Send("配料完成", UserTreeCompelete);
  575. ActionManage.GetInstance.Send("历史记录", Json<OldRecipe>.Data.Recipes);
  576. }
  577. }
  578. }
  579. });
  580. }
  581. if (maxPail <= passPail && recipeNameNum < RecipeNames.Count &&re<0&& recipNameNum_1==recipeNameNum)
  582. {
  583. SimensSend.GetInstance.SendSimens.Write<ushort>($"DB1.DBW{810 + 2 * (dnum - 1)}", 0);
  584. MessageNotify.GetInstance.ShowRunLog($"设备{dnum}桶数已清零");
  585. recipeSend.TryUpdate(ip, false, true);
  586. doDeviceCount.TryUpdate(ip, recipeNameNum + 1, doDeviceCount[ip]);
  587. recipeNameNum = doDeviceCount[ip];
  588. index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == RecipeNames.ElementAt(recipeNameNum - 1));
  589. if (index >= 0)
  590. {
  591. foreach (var rawMaterial in Recipes.ElementAt(index).RawMaterials)
  592. {
  593. if (rawMaterial.DeviceIp == DeviceInquire.GetInstance.devices[i].IpAddress)
  594. {
  595. device_Loc.Add(rawMaterial.Loc);
  596. }
  597. }
  598. }
  599. foreach (var down_Loc in device_Loc)
  600. {
  601. SimensSend.GetInstance.SendSimens.Write<bool>($"DB1.DBX{710 + 4 * (dnum - 1) + (int)((down_Loc - 1) / 8)}.{(down_Loc - 1) % 8}", true);
  602. }
  603. MessageNotify.GetInstance.ShowRunLog($"设备{dnum}下发配方桶下发成功");
  604. SimensSend.GetInstance.SendSimens.Write<ushort>($"DB1.DBW{106 + 2 * (dnum - 1)}", 500);
  605. if (dnum == 1)
  606. {
  607. App.Current.Dispatcher.Invoke(() =>
  608. {
  609. RecipeModel recipe = UserTreeWait.ElementAt(0);
  610. if (recipe != null)
  611. {
  612. recipe.RecipStatus = "正在配料";
  613. recipeProcesses.Insert(0, recipe);
  614. ActionManage.GetInstance.Send("正在配料", recipeProcesses);
  615. /* Json<OnRecipe>.Data.Recipes.Insert(0, recipe);
  616. Json<OnRecipe>.Save();*/
  617. UserTreeWait.RemoveAt(0);
  618. }
  619. });
  620. }
  621. }
  622. }
  623. }
  624. if (DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.PailArrive&& recipeNameNum - 1< RecipeNames.Count)
  625. {
  626. if (recipeNameNum > 0)
  627. {
  628. int recipecount = recipeProcesses.Count - (recipeNameNum - UserTreeCompelete.Count);
  629. #region 下料
  630. int doCount = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == RecipeNames.ElementAt(recipeNameNum - 1));
  631. if (doCount >= 0)
  632. {
  633. int re = 0;
  634. if (recipecount < recipeProcesses.Count && recipecount >= 0)
  635. {
  636. re = recipeProcesses.ElementAt(recipecount).RawMaterials.ToList().FindIndex(a => a.RawMaterialName == DeviceInquire.GetInstance.DeviceLists[ip].DeviceName && a.Loc == DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.PassPail && a.RecipeStatus == 1);
  637. if (re>=0)
  638. {
  639. float weight= recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re).RawMaterialWeight;
  640. DeviceInquire.GetInstance.DeviceLists[ip].UpdateState(weight);
  641. recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re).RecipeStatus = 2;
  642. recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re).Status = (Status)1;
  643. MessageNotify.GetInstance.ShowRunLog($"设备{dnum}配料状态:正在配料");
  644. }
  645. }
  646. }
  647. #endregion
  648. #region 正在配料记重
  649. if (recipecount < recipeProcesses.Count && recipecount >= 0&& DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.RunStatus==2)
  650. {
  651. int re_1 = recipeProcesses.ElementAt(recipecount).RawMaterials.ToList().FindIndex(a => a.RawMaterialName == DeviceInquire.GetInstance.DeviceLists[ip].DeviceName && a.Loc == DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.PassPail && a.RecipeStatus == 2);
  652. if (re_1>=0)
  653. {
  654. recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re_1).TotalWeight = DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.RealWeightFeedback;
  655. }
  656. }
  657. #endregion
  658. #region 完成计重
  659. if (DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.Finish_mt && passPail_1 == passPail - 1)
  660. {
  661. if (recipecount < recipeProcesses.Count && recipecount >= 0)
  662. {
  663. int re_1 = recipeProcesses.ElementAt(recipecount).RawMaterials.ToList().FindIndex(a => a.RawMaterialName == DeviceInquire.GetInstance.DeviceLists[ip].DeviceName && a.Loc == DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.PassPail && a.RecipeStatus == 2);
  664. if (re_1 >= 0)
  665. {
  666. Thread.Sleep(50);
  667. float xx = DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.CutWeightFeedback;
  668. recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re_1).TotalWeight = xx;
  669. float t = Math.Abs(recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re_1).TotalWeight - recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re_1).RawMaterialWeight);
  670. if (t > Json<DevicePar>.Data.BaseParModel.Limit)
  671. {
  672. SimensSend.GetInstance.SendSimens.Write<bool>("M11.2", true);
  673. while (!MessageNotify.GetInstance.ShowDialog($"设备{dnum}物料下料超出范围报警,请处理后点击确认!", DialogType.Warning))
  674. {
  675. App.Current.Dispatcher.Invoke(() => { NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"需确认处理后才能继续运行!"); });
  676. }
  677. SimensSend.GetInstance.SendSimens.Write<bool>("M11.2", false);
  678. }
  679. recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re_1).RecipeStatus = 3;
  680. recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re_1).Status = (Status)2;
  681. MessageNotify.GetInstance.ShowRunLog($"设备{dnum}配料状态:完成配料,物料状态:{recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re_1).Status}");
  682. Json<OnRecipe>.Data.Recipes = recipeProcesses;
  683. Json<OnRecipe>.Save();
  684. DeviceInquire.GetInstance.DeviceLists[ip].Reset();
  685. ActionManage.GetInstance.Send("正在配料", recipeProcesses);
  686. MessageNotify.GetInstance.ShowRunLog($"设备{dnum}已下料{recipeProcesses.ElementAt(recipecount).RawMaterials.ElementAt(re_1).TotalWeight}g");
  687. }
  688. }
  689. }
  690. #endregion
  691. }
  692. }
  693. }
  694. else
  695. {
  696. doDeviceCount.TryAdd(DeviceInquire.GetInstance.devices[i].IpAddress, 0);
  697. }
  698. }
  699. }
  700. int rep = doDeviceCount.Count(a => a.Value == 1);
  701. if ( rep== DeviceInquire.GetInstance.devices.Count&&!allowStart)
  702. {
  703. App.Current.Dispatcher.Invoke(() => { NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"可以开始放入配料桶!"); });
  704. allowStart = true;
  705. }
  706. }
  707. Thread.Sleep(10);
  708. }, "设备下发配方");
  709. MessageNotify.GetInstance.ShowRunLog($"设备下发配方运行");
  710. TaskManage.GetInstance.StartLong(() =>
  711. {
  712. string ip = "192.168.2.10";
  713. if (DeviceInquire.GetInstance.DeviceLists.ContainsKey(ip) && doDeviceCount.ContainsKey(ip)&& RecipeNames.Count>0&& doDeviceCount[ip] >0)
  714. {
  715. int maxPail = 0;
  716. int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == RecipeNames.ElementAt(doDeviceCount[ip] - 1));
  717. if (index >= 0)
  718. {
  719. foreach (var rawMaterial in Recipes.ElementAt(index).RawMaterials)
  720. {
  721. if (rawMaterial.Loc > maxPail)
  722. {
  723. maxPail = rawMaterial.Loc;
  724. }
  725. }
  726. int passing = DeviceInquire.GetInstance.DeviceLists[ip].deviceStatus.PassPail;
  727. if (pas <= maxPail && passing == pas - 1)
  728. {
  729. if (!start_Send)
  730. {
  731. SimensSend.GetInstance.SendSimens.Write<bool>("M11.5", true);
  732. MessageNotify.GetInstance.ShowRunLog($"状态:配方续桶");
  733. start_Send = true;
  734. }
  735. }
  736. if (pas <= maxPail && passing == pas)
  737. {
  738. if (start_Send)
  739. {
  740. SimensSend.GetInstance.SendSimens.Write<bool>("M11.5", false);
  741. MessageNotify.GetInstance.ShowRunLog($"状态:配方停桶");
  742. start_Send = false;
  743. pas++;
  744. }
  745. }
  746. if (pas > maxPail)
  747. {
  748. pas = 1;
  749. }
  750. }
  751. }
  752. Thread.Sleep(100);
  753. }, "起始传送带控制");
  754. }
  755. }
  756. }