//#define Debug extern alias aliyun; using BPA.Helper; using BPASmartClient.CustomResource.Pages.Model; using BPASmartClient.CustomResource.UserControls; using BPASmartClient.CustomResource.UserControls.MessageShow; using BPASmartClient.DosingSystem.ViewModel; using BPASmartClient.Model; using System; using System.Collections.Concurrent; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using aliyun.uPLibrary.Networking.M2Mqtt.Messages; using System.Collections.Generic; using aliyun::BPA.PahoMQ; using System.Configuration; using BPA.Communication; using Newtonsoft.Json; using System.Reflection; using System.Text; using BPASmartClient.DosingSystem.Model; using Microsoft.EntityFrameworkCore.Metadata.Internal; using System.Collections; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; using System.Windows.Navigation; using System.Text.RegularExpressions; using static System.Resources.ResXFileRef; using BPASmartClient.DosingSystem.Model.Dto; using BPASmartClient.DosingSystem.Model.MQTT; namespace BPASmartClient.DosingSystem { /// /// 业务逻辑执行类 /// public class ExcuteControl { private static ExcuteControl Instance; public static ExcuteControl GetInstance => Instance ??= new ExcuteControl(); public ConcurrentDictionary mqttCollection = new ConcurrentDictionary(); public ConcurrentDictionary aliyun = new ConcurrentDictionary(); public ObservableCollection Recipes { get; set; } = Json.Data.Recipes; public ObservableCollection StockStatus = new ObservableCollection(); public string CurrentRecipeName { get; set; } /// /// 当前正在制作的配方 /// public ObservableCollection recipeProcesses { get; set; } = new ObservableCollection(); /// /// 等待制作的配方 /// public ObservableCollection UserTreeWait { get; set; } = new ObservableCollection(); /// /// 已完成的配方 /// public ObservableCollection UserTreeCompelete { get; set; } = new ObservableCollection(); public ConcurrentQueue RecipeNames = new ConcurrentQueue(); /// /// 配料完成计数 /// int Comcount = 0; public static bool PropertySet = false;//云端属性设置回调主题订阅标志 public static bool PropertyReport = false; //属性上报主题订阅标志 public static bool EventReport = false; //事件上报主题订阅标志 public static bool ServiceCall = false;//服务调用回调主题订阅标志 public NameValueCollection produtInfo; public NameValueCollection mqttInfo; public NameValueCollection ConveyerInfo; public NameValueCollection ServicesInfo; public bool AliyunIsConnect = false; public ExcuteControl() { ActionManage.GetInstance.Register(new Action((o) => { if (o != null && o is string recipeName) { RecipeSend(recipeName); } }), "配方下发"); ActionManage.GetInstance.Register(new Action((ob) => { if (ob != null && ob is string recipeName) { CancelRecipe(recipeName); } }), "取消配方"); AliYunInit(); RecipeRun(); BusinessExcute(); ConveyerPropertyReport(); ThreadTaskInit(); #if Debug Task.Run(() => { while (true) { if (AliyunIsConnect) { for (int i = 0; i < 6; i++) { AliyunEventReport($"192.168.0.{i+1}0", new AliyunStockEventReportModel { Result = "1" }, "StockJerk1StatusEvent", AliyunMaterialModelType.StockModel); AliyunEventReport($"192.168.0.{i + 1}0", new AliyunStockEventReportModel { Result = "1" }, "StockServoFalutEvent", AliyunMaterialModelType.StockModel); AliyunEventReport($"192.168.0.{i + 1}0", new AliyunStockEventReportModel { Result = "1" }, "StockJerk2StatusEvent", AliyunMaterialModelType.StockModel); AliyunEventReport($"192.168.0.{i + 1}0", new AliyunStockEventReportModel { Result = "1" }, "StockUpLimitEvent", AliyunMaterialModelType.StockModel); AliyunEventReport($"192.168.0.{i + 1}0", new AliyunStockEventReportModel { Result = "1" }, "StockDownLimitEvent", AliyunMaterialModelType.StockModel); AliyunStockPropertyReportModel model = new AliyunStockPropertyReportModel(); model.StockRealWeight = 1; model.BucketRealWeight = 2; model.StockDeviceNum = 2; model.StockDeviceName = "测试"; model.StockWorkModel = 0; model.StockSlowlyAddWeight = 6; model.StockPreCloseValueWeight = 7; model.StockRapidAcceleration = 46; model.StockSlowAcceleration = 24; model.StockServoManualSpeed = 35; model.StockUpperLimitWeight = 57; model.StockLowerLimitWeight = 34; model.StockStirringSpeed = 54; model.StockMaterialType = "粉体"; model.StockBatchStatus = "待机"; StokcPropertyReport($"192.168.0.{i + 1}0", model); } AliyunConveyerPropertyReportModel model1 = new AliyunConveyerPropertyReportModel(); model1.TopBucketControlStatus = 1; model1.DownBucketControlStatus =1; model1.RunStatus = 1; model1.WorkModel = 1; model1.TopBucketSigleCheck = 1; model1.ButtonBucketSigleCheck = 1; model1.ConveyerOnlineStatus =1; var mqdeviceTestProperty = new PostPropertyParams(); mqdeviceTestProperty.sys = new Sys { ack = 1 }; mqdeviceTestProperty.method = "thing.event.property.post"; mqdeviceTestProperty.version = "1.0"; mqdeviceTestProperty.ModelName = $"{produtInfo.Get("Conveyer")}"; mqdeviceTestProperty.Model = model1; mqdeviceTestProperty.Init(); var message = JsonConvert.SerializeObject(mqdeviceTestProperty); var topic = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/property/post";//发布主题 var topicReply = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/property/post_reply";//订阅主题 if (mqttCollection.ContainsKey("Conveyer")) { try { mqttCollection["Conveyer"].Publish((op) => { op.Message = message; op.Topic = topic; op.TopicReply = topicReply; //if (!PropertyReport) //{ // op.ThresholdCallback += MqttPostProperty_MqttMsgPublishReceived; // MqttPostProperty_MqttMsgPublishReceived; // PropertyReport = true; //} }); } catch (Exception) { //throw; } } SystemEventReport("ProcessRecipe", new { RecipeName = "测试5" });//正在执行配方上报 if (UserTreeWait.Count > 0) { string[] recipeNames = new string[UserTreeWait.Count]; for (int i = 0; i < recipeNames.Length; i++) { recipeNames[i] = UserTreeWait.ElementAt(i).RecipeName; } SystemEventReport("WaitProcessRecipe", new { RecipeNames = recipeNames });//等待执行配方上报 } else { SystemEventReport("WaitProcessRecipe", new { RecipeNames = new string[] { } });//等待执行配方上报 } } Thread.Sleep(5000); } }); #endif } /// /// 阿里云连接检查 /// private void AliyunMqConnectCheck() { } public void MqttDisConnect() { ThreadManage.GetInstance.Dispose(); foreach (var item in mqttCollection) { item.Value._mqttClient?.Disconnect(); } } /// /// 连接阿里云Iot物联网平台 /// /// private async void AliYunInit() { produtInfo = (NameValueCollection)System.Configuration.ConfigurationManager.GetSection("FlexBatchSystem/ProductInfo"); mqttInfo = (NameValueCollection)System.Configuration.ConfigurationManager.GetSection("FlexBatchSystem/MqttInfo"); ConveyerInfo = (NameValueCollection)System.Configuration.ConfigurationManager.GetSection("FlexBatchSystem/ConveyerInfo"); ServicesInfo = (NameValueCollection)System.Configuration.ConfigurationManager.GetSection("FlexBatchSystem/Services"); int count = Json.Data.BaseParModel.StockCount;//料仓数 #region 料仓连接阿里云 for (int i = 0; i < count; i++) { if (!mqttCollection.ContainsKey($"Stock{i + 1}")) //创建料仓设备mqtt连接 { await Task.Run(() => { try { int num = i + 1; NameValueCollection StockInfo = ((NameValueCollection)System.Configuration.ConfigurationManager.GetSection($"FlexBatchSystem/StockInfo{num}")); var mes = new aliyun.BPA.PahoMQ.MessageHandler(new aliyun.BPA.PahoMQ.PahoMQOption() { Broker = mqttInfo.Get("mqttHostUrl"), ProductKey = produtInfo.Get("ProductKey"), DeviceName = StockInfo.Get("DeviceName"), DeviceSecret = StockInfo.Get("DeviceSecret"), Port = 1883 }); if (mes._mqttClient.IsConnected) { MessageLog.GetInstance.Show($"阿里云--料仓{num}设备激活成功!"); } else { MessageLog.GetInstance.Show($"阿里云--料仓{num}设备激活失败!"); return; } mes.Subscribe((op) => { op.TopicReply = $"/sys/{produtInfo.Get("ProductKey")}/{StockInfo.Get("DeviceName")}/thing/service/property/set"; //if (!PropertySet) //{ op.ThresholdCallback += StockPropertySetCallback; PropertyReport = true; //} }); MessageLog.GetInstance.Show($"阿里云--料仓{num}设备属性设置订阅成功!"); mqttCollection.TryAdd($"Stock{i + 1}", mes); if (!aliyun.ContainsKey($"{Json.Data.BaseParModel.NetworkSegAddress}{i + 1}0")) { aliyun.TryAdd($"{Json.Data.BaseParModel.NetworkSegAddress}{i + 1}0", $"Stock{i + 1}"); } } catch (Exception) { MessageLog.GetInstance.Show($"阿里云--料仓{i}设备激活失败!"); return; } }); } } #endregion #region 输送线连接阿里云 if (!mqttCollection.ContainsKey($"Conveyer"))//创建输送线Mqtt连接 { await Task.Run(() => { try { var res = new aliyun.BPA.PahoMQ.MessageHandler(new aliyun.BPA.PahoMQ.PahoMQOption() { Broker = mqttInfo.Get("mqttHostUrl"), ProductKey = produtInfo.Get("ProductKey"), DeviceName = ConveyerInfo.Get("DeviceName"), DeviceSecret = ConveyerInfo.Get("DeviceSecret"), Port = 1883 }); if (res._mqttClient.IsConnected) { MessageLog.GetInstance.Show($"阿里云--输送线设备激活成功!"); } else { MessageLog.GetInstance.Show($"阿里云--输送线设备激活失败!"); return; } //属性订阅 res.Subscribe((op) => { op.TopicReply = $"/sys/{produtInfo.Get("ProductKey")}/{ConveyerInfo.Get("DeviceName")}/thing/service/property/set"; //if (!PropertySet) //{ op.ThresholdCallback += ConveyerPropertySetCallback; PropertyReport = true; // } }); MessageLog.GetInstance.Show($"阿里云---输送线设备属性设置订阅成功!"); //服务订阅 for (int j = 0; j < ServicesInfo.AllKeys.Length; j++) { res.Subscribe((op) => { op.TopicReply = $"/sys/{produtInfo.Get("ProductKey")}/{ConveyerInfo.Get("DeviceName")}/thing/service/{ServicesInfo.Get(j)}"; if (!ServiceCall) { op.ThresholdCallback += ServiceCallback; ServiceCall = true; } }); MessageLog.GetInstance.Show($"阿里云--服务'{ServicesInfo.Get(j)}'订阅成功!"); } mqttCollection.TryAdd($"Conveyer", res); } catch (Exception) { MessageLog.GetInstance.Show($"阿里云--输送线设备激活失败!"); return; } }); } if (mqttCollection.ContainsKey("Conveyer")&& mqttCollection["Conveyer"]._mqttClient.IsConnected) { AliyunSystemPropertyReportModel m1 = new AliyunSystemPropertyReportModel(); m1.RecipeCollection = new string[Json.Data.Recipes.Count]; for (int i = 0; i < Json.Data.Recipes.Count; i++) { m1.RecipeCollection[i] = Json.Data.Recipes[i].RecipeName; } SystemPropertyReport(m1); } #endregion } /// /// 料仓属性上报 /// /// /// public void StokcPropertyReport(string ipaddres, T model) { var mqdeviceTestProperty = new PostPropertyParams(); mqdeviceTestProperty.sys = new Sys { ack = 1 }; mqdeviceTestProperty.method = "thing.event.property.post"; mqdeviceTestProperty.version = "1.0"; mqdeviceTestProperty.ModelName = $"{produtInfo.Get("Stock")}"; mqdeviceTestProperty.Model= model; mqdeviceTestProperty.Init(); var message = JsonConvert.SerializeObject(mqdeviceTestProperty); var topic = $"/sys/{produtInfo.Get("ProductKey")}/{aliyun[ipaddres]}/thing/event/property/post";//发布主题 var topicReply = $"/sys/{produtInfo.Get("ProductKey")}/{aliyun[ipaddres]}/thing/event/property/post_reply";//订阅主题 if (mqttCollection.ContainsKey(aliyun[ipaddres])) { try { mqttCollection[aliyun[ipaddres]].Publish((op) => { op.Message = message; op.Topic = topic; op.TopicReply = topicReply; //if (!PropertyReport) //{ // op.ThresholdCallback += MqttPostProperty_MqttMsgPublishReceived; // MqttPostProperty_MqttMsgPublishReceived; // PropertyReport = true; //} }); } catch (Exception) { //throw; } } } /// /// 料仓模板或输送线模板事件上报 /// /// /// /// public void AliyunEventReport(string ipaddres, T model, string eventFlag, AliyunMaterialModelType type) { string eventIdentifier; string deviceName; MessageHandler messageHandler = null; if (type == AliyunMaterialModelType.StockModel) { eventIdentifier = $"{produtInfo.Get("Stock")}:{eventFlag}";//格式:模板名:事件名 deviceName = aliyun[ipaddres]; if (!mqttCollection.ContainsKey(aliyun[ipaddres])) return; messageHandler = mqttCollection[aliyun[ipaddres]]; } else { eventIdentifier = $"{produtInfo.Get("Conveyer")}:{eventFlag}"; deviceName = $"{ConveyerInfo.Get("DeviceName")}"; if (!mqttCollection.ContainsKey("Conveyer")) return; messageHandler = mqttCollection["Conveyer"]; } var mqdeviceTestEvent = new PostEventParams(); mqdeviceTestEvent.id = Guid.NewGuid().ToString(); mqdeviceTestEvent.sys = new Sys { ack = 1 }; mqdeviceTestEvent.method = $"thing.event.{eventIdentifier}.post"; mqdeviceTestEvent.version = "1.0"; mqdeviceTestEvent.@params = new EventParam { value = model, time = new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds() }; var eventMessage = JsonConvert.SerializeObject(mqdeviceTestEvent); //事件上报 var eventTopic = $"/sys/{produtInfo.Get("ProductKey")}/{deviceName}/thing/event/{eventIdentifier}/post"; //事件订阅主题 var eventTopicReply = $"/sys/{produtInfo.Get("ProductKey")}/{deviceName}/thing/event/{eventIdentifier}/post_reply"; try { messageHandler.Publish((op) => { op.Message = eventMessage; op.Topic = eventTopic; op.TopicReply = eventTopicReply; //if (!EventReport) //{ // op.ThresholdCallback += MqttPostEvent_MqttMsgPublishReceived; // MqttPostProperty_MqttMsgPublishReceived; // EventReport = true; //} }); } catch (Exception) { //throw; } } /// /// 输送线模板属性上报 /// public void ConveyerPropertyReport() { TaskManage.GetInstance.StartLong(() => { if (mqttCollection.ContainsKey("Conveyer") && mqttCollection["Conveyer"]._mqttClient.IsConnected) { AliyunConveyerPropertyReportModel model = new AliyunConveyerPropertyReportModel(); model.TopBucketControlStatus = Convert.ToInt32(SiemensDevice.GetInstance.MySiemens.Read("DB5.DBX4.0").Content); model.DownBucketControlStatus = Convert.ToInt32(SiemensDevice.GetInstance.MySiemens.Read("DB5.DBX4.1").Content); model.RunStatus = Convert.ToInt32(SiemensDevice.GetInstance.MySiemens.Read("M10.0").Content); model.WorkModel = Convert.ToInt32(SiemensDevice.GetInstance.MySiemens.Read("M10.1").Content); model.TopBucketSigleCheck = Convert.ToInt32(GlobalDevice.PlcData.OnDetection); model.ButtonBucketSigleCheck = Convert.ToInt32(GlobalDevice.PlcData.UnderDetection); model.ConveyerOnlineStatus = Convert.ToInt32(SiemensDevice.GetInstance.MySiemens.IsConnected()); var mqdeviceTestProperty = new PostPropertyParams(); mqdeviceTestProperty.sys = new Sys { ack = 1 }; mqdeviceTestProperty.method = "thing.event.property.post"; mqdeviceTestProperty.version = "1.0"; mqdeviceTestProperty.ModelName = $"{produtInfo.Get("Conveyer")}"; mqdeviceTestProperty.Model = model; mqdeviceTestProperty.Init(); var message = JsonConvert.SerializeObject(mqdeviceTestProperty); var topic = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/property/post";//发布主题 var topicReply = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/property/post_reply";//订阅主题 if (mqttCollection.ContainsKey("Conveyer")) { try { mqttCollection["Conveyer"].Publish((op) => { op.Message = message; op.Topic = topic; op.TopicReply = topicReply; //if (!PropertyReport) //{ // op.ThresholdCallback += MqttPostProperty_MqttMsgPublishReceived; // MqttPostProperty_MqttMsgPublishReceived; // PropertyReport = true; //} }); } catch (Exception) { //throw; } } } Thread.Sleep(1000); }, "输送线属性上报", true); } /// /// 业务系统事件上报 /// /// /// public void SystemEventReport(string eventFlag, T t) { var eventIdentifier = eventFlag; var mqdeviceTestEvent = new PostEventParams(); mqdeviceTestEvent.id = Guid.NewGuid().ToString(); mqdeviceTestEvent.sys = new Sys { ack = 1 }; mqdeviceTestEvent.method = $"thing.event.{eventIdentifier}.post"; mqdeviceTestEvent.version = "1.0"; mqdeviceTestEvent.@params = new EventParam { value = t, time = new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds() }; var eventMessage = JsonConvert.SerializeObject(mqdeviceTestEvent); //事件上报 var eventTopic = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/{eventIdentifier}/post"; //事件订阅主题 var eventTopicReply = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/{eventIdentifier}/post_reply"; if (mqttCollection.ContainsKey("Conveyer")) { try { mqttCollection["Conveyer"].Publish((op) => { op.Message = eventMessage; op.Topic = eventTopic; op.TopicReply = eventTopicReply; //if (!EventReport) //{ // op.ThresholdCallback += MqttPostEvent_MqttMsgPublishReceived; // MqttPostProperty_MqttMsgPublishReceived; // EventReport = true; //} }); } catch (Exception) { // throw; } } } /// /// 业务系统属性上报 /// public void SystemPropertyReport(T model) { var mqdeviceTestProperty = new PostPropertyParams(); mqdeviceTestProperty.sys = new Sys { ack = 1 }; mqdeviceTestProperty.method = "thing.event.property.post"; mqdeviceTestProperty.version = "1.0"; mqdeviceTestProperty.Model = model; mqdeviceTestProperty.Init(); var message = JsonConvert.SerializeObject(mqdeviceTestProperty); var topic = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/property/post";//发布主题 var topicReply = $"/sys/{produtInfo.Get("ProductKey")}/Conveyer/thing/event/property/post_reply";//订阅主题 if (mqttCollection.ContainsKey("Conveyer")) { try { mqttCollection["Conveyer"].Publish((op) => { op.Message = message; op.Topic = topic; op.TopicReply = topicReply; //if (!PropertyReport) //{ // op.ThresholdCallback += MqttPostProperty_MqttMsgPublishReceived; // MqttPostProperty_MqttMsgPublishReceived; // PropertyReport = true; //} }); } catch (Exception) { //throw; } } } /// /// 云端属性设置回调方法-输送线模板 /// /// /// /// private void ConveyerPropertySetCallback(object sender, MqttMsgPublishEventArgs e) { if (Regex.IsMatch(e.Topic, "[0-9a-zA-Z/]*(thing/service/property/set)$")) { var rtn = JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(e.Message, 0, e.Message.Length)); PropertyInfo property = rtn.@params.GetType().GetProperty("Root"); string result = property.GetValue(rtn.@params).ToString(); var array = result.Replace("\r\n", "").Replace(" ", "").Replace("{", "").Replace("}", "").Replace("\"", "").Split(','); foreach (var item in array) { var str = item.Split(":"); //数据格式: if (str.Length >= 3) { switch (str[1]) { case "TopBucketControlStatus": SiemensDevice.GetInstance.MySiemens.Write("DB5.DBX4.0", Convert.ToBoolean(int.Parse(str[2]))); MessageNotify.GetInstance.ShowRunLog($"云端控制上桶位气缸,状态值:{str[2]}"); break; case "DownBucketControlStatus": SiemensDevice.GetInstance.MySiemens.Write("DB5.DBX4.1", Convert.ToBoolean(int.Parse(str[2]))); MessageNotify.GetInstance.ShowRunLog($"云端控制下桶位气缸,状态值:{str[2]}"); break; } } } } } /// /// 云端属性设置回调方法-料仓模板 /// /// /// public void StockPropertySetCallback(object sender, MqttMsgPublishEventArgs e) { if (Regex.IsMatch(e.Topic, "[0-9a-zA-Z/]*(thing/service/property/set)$")) { var rtn = JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(e.Message, 0, e.Message.Length)); PropertyInfo property = rtn.@params.GetType().GetProperty("Root"); string result = property.GetValue(rtn.@params).ToString(); var array = result.Replace("\r\n", "").Replace(" ", "").Replace("{", "").Replace("}", "").Replace("\"", "").Split(','); foreach (var item in array) { var str = item.Split(":"); //数据格式: string ip = $"{Json.Data.BaseParModel.NetworkSegAddress}{e.Topic.Split('/')[3].Substring(e.Topic.Split('/')[3].Length - 1, 1)}0"; switch (str[1]) { case "StockSlowlyAddWeight": DeviceInquire.GetInstance.GetDevice(ip).modbusTcp.Write(DeviceAddress.SlowlyAddWeight.ToAdd(), float.Parse(str[2])); MessageNotify.GetInstance.ShowRunLog($"云端对料仓设备{ip}设置慢加重量:值:{str[2]}"); break; case "StockPreCloseValueWeight": DeviceInquire.GetInstance.GetDevice(ip).modbusTcp.Write(DeviceAddress.PreCloseValveWeight.ToAdd(), float.Parse(str[2])); MessageNotify.GetInstance.ShowRunLog($"云端对料仓设备{ip}设置提前关阀重量:值:{str[2]}"); break; case "StockRapidAcceleration": DeviceInquire.GetInstance.GetDevice(ip).modbusTcp.Write(DeviceAddress.RapidAcceleration.ToAdd(), uint.Parse(str[2])); MessageNotify.GetInstance.ShowRunLog($"云端对料仓设备{ip}设置快加速:值:{str[2]}"); break; case "StockSlowAcceleration": DeviceInquire.GetInstance.GetDevice(ip).modbusTcp.Write(DeviceAddress.SlowAcceleration.ToAdd(), uint.Parse(str[2])); MessageNotify.GetInstance.ShowRunLog($"云端对料仓设备{ip}设置慢慢重量:值:{str[2]}"); break; case "StockServoManualSpeed": DeviceInquire.GetInstance.GetDevice(ip).modbusTcp.Write(DeviceAddress.ServoManualSpeed.ToAdd(), uint.Parse(str[2])); MessageNotify.GetInstance.ShowRunLog($"云端对料仓设备{ip}设置伺服手动速度:值:{str[2]}"); break; case "StockUpperLimitWeight": DeviceInquire.GetInstance.GetDevice(ip).modbusTcp.Write(DeviceAddress.SiloUpperLimitWeight.ToAdd(), uint.Parse(str[2])); MessageNotify.GetInstance.ShowRunLog($"云端对料仓设备{ip}设置上限重量:值:{str[2]}"); break; case "StockLowerLimitWeight": DeviceInquire.GetInstance.GetDevice(ip).modbusTcp.Write(DeviceAddress.LowerLimitWeightOfSilo.ToAdd(), uint.Parse(str[2])); MessageNotify.GetInstance.ShowRunLog($"云端对料仓设备{ip}设置下限重量:值:{str[2]}"); break; case "StockStrringSpeed": DeviceInquire.GetInstance.GetDevice(ip).modbusTcp.Write(DeviceAddress.StirringSpeed.ToAdd(), uint.Parse(str[2])); MessageNotify.GetInstance.ShowRunLog($"云端对料仓设备{ip}设置搅拌速度:值:{str[2]}"); break; } } } } /// /// 云端服务调用回调方法 /// /// /// /// private void ServiceCallback(object sender, MqttMsgPublishEventArgs e) { if (Regex.IsMatch(e.Topic, "[0-9a-zA-Z/]*thing/service/[0-9a-zA-Z:]*$")) { var rtn = JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(e.Message, 0, e.Message.Length)); PropertyInfo property = rtn.@params.GetType().GetProperty("Root"); string result = property.GetValue(rtn.@params).ToString(); var array = result.Replace("\r\n", "").Replace(" ", "").Replace("{", "").Replace("}", "").Replace("\"", "").Split(','); //单一服务调用 string res = e.Topic.Split("/")[e.Topic.Split("/").Length - 1]; if (res.Contains(":")) //自定义模板 { var arr = res.Split(":"); switch (arr[0]) { case "ConveyerModel": switch (arr[1]) { case "RunControlService": if (array.Count() == 1) { SiemensDevice.GetInstance.MySiemens.Write("M10.0", Convert.ToBoolean(int.Parse(array[0].Split(":")[1])));//输送下启停控制 MessageNotify.GetInstance.ShowRunLog($"云端对输送线进行启动控制,值:{array[0].Split(":")[1]}"); } break; case "StockAirControlService": if (array.Count() == 2) { var info = array[0].Split(":"); var info1 = array[1].Split(":"); if (info[0].Equals("StockNum")) { var addRes = SiemensDevice.GetInstance.GetSiemensBitSingleAdd("DB5.DBX", int.Parse(info[1]));//输送线配料气杠控制 SiemensDevice.GetInstance.MySiemens.Write(addRes, Convert.ToBoolean(int.Parse(info1[1]))); MessageNotify.GetInstance.ShowRunLog($"云端对输送线配料{info[1]}气缸进行升降控制,值:{info1[1]}"); } else { var addRes = SiemensDevice.GetInstance.GetSiemensBitSingleAdd("DB5.DBX", int.Parse(info1[1])); SiemensDevice.GetInstance.MySiemens.Write(addRes, Convert.ToBoolean(int.Parse(info[1]))); MessageNotify.GetInstance.ShowRunLog($"云端对输送线配料{info[1]}气缸进行升降控制,值:{info[1]}"); } } break; } break; case "StockModel": break; } } else //默认模板 { switch (res) { case "RecipeSendService": var info = array[0].Split(":"); RecipeSend(info[1]); MessageNotify.GetInstance.ShowRunLog($"云端下发配方:{info[1]}"); break; case "CancelRecipeService": var info2 = array[0].Split(":"); CancelRecipe(info2[1]); MessageNotify.GetInstance.ShowRunLog($"云端取消配方:{info2[1]}"); break; } } } } /// /// 多线程接收工单配方数据。 /// private void ThreadTaskInit() { TaskManage.GetInstance.StartLong(new Action(() => { while (MqttServer.GetInstance.WorkOrders.Count > 0) { if (MqttServer.GetInstance.WorkOrders.TryDequeue(out WorkOrderPusht wod)) { App.Current?.Dispatcher?.Invoke(new Action(() => { //TODO:工单数据处理,直接新建配方。 foreach (var recipe in wod.ProductList) { var tempRecipe = new RecipeModel(); var tempMaterials = new ObservableCollection(); if (Json.Data.Recipes.Any(p => p.RecipCode == recipe.Id)) { continue; } else { tempRecipe.RecipCode = recipe.Id; } tempRecipe.RecipeName = recipe.Name; foreach (var material in recipe.BOMEntryList) { tempMaterials.Add(new RawMaterialModel() { RawMaterialName = material.MaterialName, DeviceIp="", Loc=1, RawMaterialWeight=(uint)material.BomQty, RawMaterialSource=0, RawMaterialId=material.MaterialId, }); } tempRecipe.RawMaterials = tempMaterials; Json.Data.Recipes.Add(tempRecipe); } })); } } Thread.Sleep(500); }), "工单信息监听"); } /// /// 取消配方 /// /// public async void CancelRecipe(string RecipeName) { if (RecipeName != null) { //var res = MessageNotify.GetInstance.ShowDialog($"是否取消配方 【{RecipeName}】制作", DialogType.Warning); //if (res) //{ int index = Recipes.ToList().FindIndex(p => p.RecipeName == RecipeName); if (index >= 0 && index < Recipes.Count) { await Task.Factory.StartNew(new Action(() => { Recipes.ElementAt(index).IsEnable = true; Json.Data.Recipes.ElementAt(index).IsEnable = true; Recipes.ElementAt(index).Are.Set(); App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); })); SiemensDevice.GetInstance.MySiemens.Write("M10.5", true); MessageNotify.GetInstance.ShowRunLog($"M10.5:true"); Thread.Sleep(1000); SiemensDevice.GetInstance.MySiemens.Write("M10.5", false); MessageNotify.GetInstance.ShowRunLog($"M10.5:false"); App.Current.Dispatcher.Invoke(() => { NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方 [{RecipeName}] 取消成功"); }); MessageNotify.GetInstance.ShowUserLog($"取消配方制作 {RecipeName}"); //取消成功 })); } else { //取消失败 } //} } else { MessageNotify.GetInstance.ShowUserLog($"配方 {RecipeName}取消失败"); } } /// /// 配方下发 /// public void RecipeSend(string RecipeName) { if (RecipeName != null) { int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == RecipeName); if (index >= 0 && index < Recipes.Count) { for (int i = 0; i < Recipes.ElementAt(index).RawMaterials.Count; i++) { if (Recipes.ElementAt(index).RawMaterials.ElementAt(i).RawMaterialSource == 1) { string ip = Recipes.ElementAt(index).RawMaterials.ElementAt(i).DeviceIp; var device = DeviceInquire.GetInstance.GetDevice(ip); if (ip == null && ip == "") { 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); return; } if (!device.IsConnected) { MessageNotify.GetInstance.ShowDialog($"设备 【{device.DeviceName}】 未连接,不允许下发此配方", DialogType.Error); return; } } } Recipes.ElementAt(index).IsEnable = false; Json.Data.Recipes.ElementAt(index).IsEnable = false; } MessageNotify.GetInstance.ShowUserLog($"下发工单 {Recipes.ElementAt(index).RecipeName}"); RecipeNames.Enqueue(RecipeName); var res = Recipes.FirstOrDefault(p => p.RecipeName == RecipeName); App.Current.Dispatcher.Invoke(() => { UserTreeWait.Add(new RecipeModel { RecipStatus = "等待制作", SerialNum = UserTreeWait.Count + 1, RecipeName = RecipeName, RawMaterials = res.RawMaterials }); }); } App.Current.Dispatcher.Invoke(() => { NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方下发成功!"); }); } /// /// 配方业务执行 /// private void RecipeRun() { TaskManage.GetInstance.StartLong(new Action(() => { if (RecipeNames.Count > 0) { int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == RecipeNames.ElementAt(0)); if (index >= 0 && index < Recipes.Count) { Recipes.ElementAt(index).Are.Reset(); Recipes.ElementAt(index).IsEnable = false; StockStatus.Clear(); App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); if (UserTreeWait.Count > 0) App.Current.Dispatcher.Invoke(() => { UserTreeWait.RemoveAt(0); }); })); CurrentRecipeName = Recipes.ElementAt(index).RecipeName; #region 执行配方以及等待执行配方上报 SystemEventReport("ProcessRecipe", new { RecipeName = CurrentRecipeName });//正在执行配方上报 if (UserTreeWait.Count > 0) { string[] recipeNames = new string[UserTreeWait.Count]; for (int i = 0; i < recipeNames.Length; i++) { recipeNames[i] = UserTreeWait.ElementAt(i).RecipeName; } SystemEventReport("WaitProcessRecipe", new { RecipeNames = recipeNames });//等待执行配方上报 } else { SystemEventReport("WaitProcessRecipe", new { RecipeNames=new string[] { } });//等待执行配方上报 } #endregion #region 配方下发到PLC操作相关 //配方数据写入到输送机 var res = Json.Data.Recipes.FirstOrDefault(p => p.RecipeName == CurrentRecipeName); List BarrelNum = new List(); ConcurrentDictionary values = new(); if (res != null) { var tInfo = res.RawMaterials.GroupBy(p => p.Loc);//获取桶号信息 if (tInfo != null) { for (int i = 0; i < tInfo.Count(); i++) { int data = 0; for (int m = 0; m < tInfo.ElementAt(i).Count(); m++) { var TempName = tInfo.ElementAt(i).ElementAt(m).RawMaterialName; var tempDevice = DeviceInquire.GetInstance.devices.FirstOrDefault(p => p.DeviceName == TempName); if (tempDevice != null) { /*data = data.SetBitValue((byte)tempDevice.DeviceNum, true);*/ if (tempDevice.DeviceNum > 0) { // //int a = data.SetBitValue((byte)tInfo.ElementAt(i).ElementAt(m).Loc, true); // //byte[] test1 = a.ToBytes(BPA.Helper.DataFormat.BADC); // //int item = test1.ToInt(); // int item = data.SetBitValue((byte)tInfo.ElementAt(i).ElementAt(m).Loc, true).ToBytes(BPA.Helper.DataFormat.BADC).ToInt(); // int item1 = SiemensDevice.GetInstance.MySiemens.Read($"DB4.DBD{2 + (tempDevice.DeviceNum - 1) * 4}").Content; ////prop1: // var RE = SiemensDevice.GetInstance.MySiemens.Write($"DB4.DBD{2 + (tempDevice.DeviceNum - 1) * 4}", item + item1); // //var values = SiemensDevice.GetInstance.MySiemens.Read($"DB4.DBD{2 + (tempDevice.DeviceNum - 1) * 4}"); // //if ((values != null && values.ToString() != (item + item1).ToString()) || values == null) // // goto prop1; // if (RE.IsSuccess) // MessageNotify.GetInstance.ShowRunLog($"下发配方DB4.DBD{2 + (tempDevice.DeviceNum - 1) * 4} :{(byte)tInfo.ElementAt(i).ElementAt(m).Loc}-{item + item1}-{(item + item1).ToBinString()}"); // else // MessageNotify.GetInstance.ShowRunLog($"下发配方DB4.DBD{2 + (tempDevice.DeviceNum - 1) * 4} 失败"); int item = data.SetBitValue((byte)tInfo.ElementAt(i).ElementAt(m).Loc, true).ToBytes(BPA.Helper.DataFormat.BADC).ToInt(); string tempAdd = $"DB4.DBD{2 + (tempDevice.DeviceNum - 1) * 4}"; if (!values.ContainsKey(tempAdd)) values.TryAdd(tempAdd, new int[2] { 0, 0 }); values[tempAdd][0] = values[tempAdd][0] + item; values[tempAdd][1] = tInfo.ElementAt(i).ElementAt(m).Loc; } } if (tInfo.ElementAt(i).ElementAt(m).Loc > 0) { if (!BarrelNum.Contains(tInfo.ElementAt(i).ElementAt(m).Loc)) { BarrelNum.Add(tInfo.ElementAt(i).ElementAt(m).Loc); } } } } } } values?.ToList().ForEach(x => { SiemensDevice.GetInstance.MySiemens.Write(x.Key, x.Value[0]).OnSuccess(() => { MessageNotify.GetInstance.ShowRunLog($"下发配方-{x.Key} :桶数:[{x.Value[1]}]-{x.Value[0].ToBinString()}"); }).OnFail(s => { MessageNotify.GetInstance.ShowRunLog($"下发配方-{x.Key} 失败"); }); }); SiemensDevice.GetInstance.MySiemens.Write("DB4.DBD198", BarrelNum.Count);//配方使用桶数写入 SiemensDevice.GetInstance.MySiemens.Write("DB4.DBX0.1", true);//配方执行启动 Stopwatch sw = new Stopwatch(); var recipe = Recipes.ElementAt(index); ObservableCollection RawMater = new ObservableCollection(); foreach (var item in recipe.RawMaterials) { RawMater.Add(new RawMaterialModel() { RawMaterialName = item.RawMaterialName, DeviceIp = item.DeviceIp, DownLimtFeedback = item.DownLimtFeedback, Loc = item.Loc, RawMaterialId = item.RawMaterialId, RawMaterialSource = item.RawMaterialSource, RawMaterialType = item.RawMaterialType, RawMaterialWeight = item.RawMaterialWeight, RecipeStatus = item.RecipeStatus, SelectIndex = item.SelectIndex, Status = item.Status, UpLimtFeedback = item.UpLimtFeedback, UpLimtWeightFeedback = item.UpLimtWeightFeedback, WeightFeedback = item.WeightFeedback, }); } App.Current.Dispatcher.Invoke(() => { recipeProcesses.Add(new RecipeModel() { RawMaterials = RawMater, IsEnable = recipe.IsEnable, RecipeName = recipe.RecipeName, SerialNum = recipe.SerialNum, RecipCode = recipe.RecipCode, }); }); sw.Restart(); while (true) { if (sw.ElapsedMilliseconds >= 3000 && !GlobalDevice.PlcData.ResComplete) { MessageNotify.GetInstance.ShowRunLog("获取配方下发反馈超时"); break; } if (GlobalDevice.PlcData.ResComplete) { SiemensDevice.GetInstance.MySiemens.Write("DB3.DBX0.1", false); break; } Thread.Sleep(100); } #endregion Recipes.ElementAt(index).Are.WaitOne();//阻塞,直到当前配方完成 RecipeNames.TryDequeue(out string deviceName); var recipeComple = Recipes.ElementAt(index); ObservableCollection RawMaterComple = new ObservableCollection(); foreach (var item in recipeComple.RawMaterials) { RawMaterComple.Add(new RawMaterialModel() { RawMaterialName = item.RawMaterialName, DeviceIp = item.DeviceIp, DownLimtFeedback = item.DownLimtFeedback, Loc = item.Loc, RawMaterialId = item.RawMaterialId, RawMaterialSource = item.RawMaterialSource, RawMaterialType = item.RawMaterialType, RawMaterialWeight = item.RawMaterialWeight, RecipeStatus = item.RecipeStatus, SelectIndex = item.SelectIndex, Status = item.Status, UpLimtFeedback = item.UpLimtFeedback, UpLimtWeightFeedback = item.UpLimtWeightFeedback, WeightFeedback = item.WeightFeedback, }); } App.Current.Dispatcher.Invoke(() => { UserTreeCompelete.Add(new RecipeModel() { RawMaterials = RawMaterComple, IsEnable = recipeComple.IsEnable, RecipeName = recipeComple.RecipeName, SerialNum = UserTreeCompelete.Count + 1, RecipCode = recipeComple.RecipCode, RecipStatus = "制作完成" }); }); App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); CurrentRecipeName = string.Empty; }));//完成后清空当前配方 } } Thread.Sleep(100); }), "启动配方下发", true); } /// /// 配料逻辑 /// /// 当前执行的配方 public void BusinessExcute() { ThreadManage.GetInstance.StartLong(new Action(() => { #region 测试 ////拿到当前配方 //for (int j = 0; j < GlobalDevice.PlcData.IsAllowIngredients.Length; j++)//遍历允许配料的料桶 //{ // if (GlobalDevice.PlcData.IsAllowIngredients[j]) // { // int barrelNum = j + 1;//桶号 // int stockLoc = GlobalDevice.PlcData.LocationFeedback[j];//允许配料的料仓位置 0~6 双仓情况下返回的位置是否一样,料仓ip设置顺序怎样的 // if (stockLoc >= 1 && stockLoc <= Json.Data.BaseParModel.StockCount) // { // int index = Array.FindIndex(DeviceInquire.GetInstance.devices.ToArray(), p => p.DeviceNum == stockLoc); // if (index >= 0) // { // //查出到配料位置的原料 // int result = Array.FindIndex(recipeModel.RawMaterials.ToArray(), p => (p.Loc == barrelNum && p.DeviceIp == DeviceInquire.GetInstance.devices.ElementAt(index).IpAddress));//待定 // if (result != -1 && DeviceInquire.GetInstance.GetDevice(recipeModel.RawMaterials[result].DeviceIp).deviceStatus.RunStatus == 1 && RecipeControlViewModel.recipeProcesses.ElementAt(0).RawMaterials[result].Status == Status.等待配料) // { // var weight = recipeModel.RawMaterials[result].RawMaterialWeight; // DeviceInquire.GetInstance.GetDevice(recipeModel.RawMaterials.ElementAt(index).DeviceIp).Start(weight);//所有参数下发并启动配料 // MessageNotify.GetInstance.ShowRunLog($"{recipeModel.RawMaterials[result].DeviceIp}:正在配料"); // RecipeControlViewModel.recipeProcesses.ElementAt(0).RawMaterials[result].Status = Status.正在配料; // } // } // } // else // { // continue; // } // } //} ////配料完成后逻辑 //for (int k = 0; k < recipeModel.RawMaterials.Count; k++) //{ // if (DeviceInquire.GetInstance.GetDevice(recipeModel.RawMaterials.ElementAt(k).DeviceIp).deviceStatus.RunStatus == 3 && RecipeControlViewModel.recipeProcesses.ElementAt(0).RawMaterials[k].Status != Status.配料完成)//配料完成 // { // int DeviceNum = DeviceInquire.GetInstance.GetDevice(recipeModel.RawMaterials.ElementAt(k).DeviceIp).deviceStatus.DeviceNum; // Comcount++; // DeviceInquire.GetInstance.GetDevice(recipeModel.RawMaterials.ElementAt(k).DeviceIp).StatusReset();//料仓复位 // SiemensDevice.GetInstance.MySiemens.Write($"DB4.DBX130.{DeviceNum - 1}", true); // Task.Run(() => // { // int cout = DeviceNum - 1; // while (!SiemensDevice.GetInstance.MySiemens.Read($"DB3.DBX148.{cout}").Content) //DB3.DBX148.0-31 148.0-148.5代表6个料仓位置 // { // SiemensDevice.GetInstance.MySiemens.Write($"DB4.DBX130.{cout}", true); // Thread.Sleep(200); // } // while (SiemensDevice.GetInstance.MySiemens.Read($"DB3.DBX148.{cout}").Content) // { // SiemensDevice.GetInstance.MySiemens.Write($"DB4.DBX130.{cout}", false); // } // MessageNotify.GetInstance.ShowRunLog($"{cout}号气缸复位信号写入成功!"); // }); // RecipeControlViewModel.recipeProcesses.ElementAt(0).RawMaterials[k].Status = Status.配料完成; // if (Comcount >= recipeModel.RawMaterials.Count) //配方配料完成 StockStatus.Count >= Recipes.ElementAt(i).RawMaterials.Count && // { // Comcount = 0; // App.Current.Dispatcher.Invoke(new Action(() => { RecipeControlViewModel.recipeProcesses.Clear(); })); // MessageNotify.GetInstance.ShowUserLog($"配方:{recipeModel.RecipeName},配料完成"); // SiemensDevice.GetInstance.MySiemens.Write("DB4.DBX202.0", true);//配料完成 // MessageNotify.GetInstance.ShowRunLog($"配方:{recipeModel.RecipeName},配料完成"); // recipeModel.Are.Set();//待定 // Thread.Sleep(100); // } // } //} #endregion #region 正式版 for (int i = 0; i < Recipes.Count; i++) { for (int m = 0; m < Recipes.ElementAt(i).RawMaterials.Count; m++) { var RunStatus = DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp).deviceStatus.RunStatus; //设备状态显示 if (Recipes.ElementAt(i).RecipeName == CurrentRecipeName) { string tempRawMaterialName = DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp).DeviceName; int recIndex = recipeProcesses.ToList().FindIndex(p => p.RecipeName == CurrentRecipeName); if (recIndex >= 0 && recIndex < recipeProcesses.Count) { int index = recipeProcesses.ElementAt(recIndex).RawMaterials.ToList().FindIndex(p => p.RawMaterialName == tempRawMaterialName); if (index >= 0 && index < recipeProcesses.ElementAt(recIndex).RawMaterials.Count) { //测试使用 recipeProcesses.ElementAt(recIndex).RawMaterials.ElementAt(index).RecipeStatus = RunStatus; } for (int j = 0; j < GlobalDevice.PlcData.IsAllowIngredients.Length; j++) { if (GlobalDevice.PlcData.IsAllowIngredients[j]) { int barrel = j + 1;//桶号 int cnt = GlobalDevice.PlcData.LocationFeedback[j];//允许配料的位置 1~6 if (RTrig.GetInstance($"a{j}").Start(GlobalDevice.PlcData.IsAllowIngredients[j])) { MessageNotify.GetInstance.ShowRunLog($"桶号:{barrel},位置:{cnt},允许配料"); } int Location1 = 0; int Location2 = 0; if (cnt == -1) { MessageNotify.GetInstance.ShowRunLog("错误"); return; } else { if (cnt >= 1 && cnt <= 6) { int a1 = Array.FindIndex(DeviceInquire.GetInstance.devices.ToArray(), p => p.DeviceNum == cnt); if (a1 >= 0) { Location1 = Array.FindIndex(Recipes.ElementAt(i).RawMaterials.ToArray(), p => p.RawMaterialName == DeviceInquire.GetInstance.devices.ElementAt(a1).DeviceName && p.Loc == barrel); } } } if (Location1 >= 0) { string RawName = Recipes.ElementAt(i).RawMaterials.ElementAt(Location1).RawMaterialName; int abc = Array.FindIndex(DeviceInquire.GetInstance.devices.ToArray(), p => p.DeviceName == RawName); int DeviceNum = DeviceInquire.GetInstance.devices.ElementAt(abc).DeviceNum; if (DeviceNum > 0) { float weight = Recipes.ElementAt(i).RawMaterials.ElementAt(Location1).RawMaterialWeight; int loc = Array.FindIndex(Recipes.ElementAt(i).RawMaterials.ToArray(), p => (p.RawMaterialName == RawName)); if (loc >= 0 && RawName != null && weight >= 0) { int St_index = Array.FindIndex(StockStatus.ToArray(), p => p.MaterialName == RawName); if (St_index < 0) //|| (StockStatus.Count < materialCount && St_index > 0) { StockStatus.Add(new StockStatusModel() { MaterialName = RawName, IssueWeight = weight, IssueStatus = 0, }); } St_index = Array.FindIndex(StockStatus.ToArray(), p => p.MaterialName == RawName);//&& p.IssueStatus == 0) if (St_index >= 0) { if (RTrig.GetInstance($"ac{j}-{St_index}").Start(GlobalDevice.PlcData.IsAllowIngredients[j])) { MessageNotify.GetInstance.ShowRunLog($"{St_index}-{j}--》允许配料"); if (StockStatus.ElementAt(St_index).IssueStatus == 2) { StockStatus.ElementAt(St_index).IssueStatus = 0; MessageNotify.GetInstance.ShowRunLog($"{St_index}-复位"); } } var rrr = DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(loc).DeviceIp).deviceStatus.RunStatus; if ((recipeProcesses.ElementAt(recIndex).RawMaterials.ElementAt(loc).RecipeStatus == 1 && StockStatus.ElementAt(St_index).IssueStatus == 0))// { StockStatus.ElementAt(St_index).IssueStatus = 1; DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(loc).DeviceIp).Start(weight); var res = recipeProcesses.ElementAt(recIndex).RawMaterials.FirstOrDefault(p => p.Status != Status.正在配料 && p.Status != Status.配料完成 && p.RawMaterialName == tempRawMaterialName && p.Loc == j + 1); if (res != null) res.Status = Status.正在配料; MessageNotify.GetInstance.ShowRunLog($"设备执行状态:{rrr}"); MessageNotify.GetInstance.ShowRunLog($"柔性味魔方{Recipes.ElementAt(i).RawMaterials.ElementAt(loc).DeviceIp},开始出料"); } if (recipeProcesses.ElementAt(recIndex).RawMaterials.ElementAt(loc).RecipeStatus == 3 && StockStatus.ElementAt(St_index).IssueStatus == 1) { //GlobalDevice.PlcData.IsAllowIngredients[j] = false;//测试使用 Comcount++; StockStatus.ElementAt(St_index).IssueStatus = 2; DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(loc).DeviceIp).StatusReset(); //int a = 0.SetBitValue((byte)(DeviceNum), true); //byte[] test1 = a.ToBytes(BPA.Helper.DataFormat.BADC); //int item = test1.ToInt(); //prop1: // SiemensDevice.GetInstance.MySiemens.Write("DB4.DBD130", item); SiemensDevice.GetInstance.MySiemens.Write($"DB4.DBX130.{DeviceNum - 1}", true); Task.Run(() => { int cout = DeviceNum - 1; while (!SiemensDevice.GetInstance.MySiemens.Read($"DB3.DBX148.{cout}").Content) //DB3.DBX148.0-31 148.0-148.5代表6个料仓位置 { SiemensDevice.GetInstance.MySiemens.Write($"DB4.DBX130.{cout}", true); Thread.Sleep(200); } while (SiemensDevice.GetInstance.MySiemens.Read($"DB3.DBX148.{cout}").Content) { SiemensDevice.GetInstance.MySiemens.Write($"DB4.DBX130.{cout}", false); } MessageNotify.GetInstance.ShowRunLog($"{cout}号气缸复位信号写入成功!"); }); var res = recipeProcesses.ElementAt(recIndex).RawMaterials.FirstOrDefault(p => p.Status != Status.配料完成 && p.RawMaterialName == tempRawMaterialName && p.Loc == j + 1); if (res != null) res.Status = Status.配料完成; MessageNotify.GetInstance.ShowRunLog($"设备完成执行状态:{rrr}"); MessageNotify.GetInstance.ShowRunLog($"柔性味魔方{Recipes.ElementAt(i).RawMaterials.ElementAt(loc).DeviceIp},出料完成,状态复位"); } } } } } } } if (Comcount >= Recipes.ElementAt(i).RawMaterials.Count) //配方配料完成 StockStatus.Count >= Recipes.ElementAt(i).RawMaterials.Count && { SystemEventReport("RecipeCompleteEvent", new AliyunSystemEventReportModel { RecipeName = CurrentRecipeName }); int cc = recipeProcesses.ElementAt(recIndex).RawMaterials.OrderBy(p => p.RawMaterialName).Count(); for (int k = 0; k < 32; k++) { for (int l = 0; l < cc; l++) { RTrig.GetInstance($"ac{k}-{l}").Start(false); } } Comcount = 0; StockStatus.Clear(); MessageNotify.GetInstance.ShowUserLog($"配方:{recipeProcesses.ElementAt(recIndex).RecipeName},配料完成"); foreach (var item in recipeProcesses.ElementAt(recIndex).RawMaterials) { MessageNotify.GetInstance.ShowUserLog($"原料:{item.RawMaterialName},桶号:{item.Loc},设定配料重量{item.RawMaterialWeight}g,实际配料重量{item.UpLimtWeightFeedback}g"); } SiemensDevice.GetInstance.MySiemens.Write("DB4.DBX202.0", true);//配料完成 MessageNotify.GetInstance.ShowRunLog($"配方:{CurrentRecipeName},配料完成"); int recipIndex = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == CurrentRecipeName); App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); })); Recipes.ElementAt(recipIndex).IsEnable = true; Json.Data.Recipes.ElementAt(recipIndex).IsEnable = true; Recipes.ElementAt(recipIndex).Are.Set(); Thread.Sleep(100); } } } } } #endregion Thread.Sleep(10); }), "配料业务逻辑"); } } }