@@ -2,8 +2,12 @@ | |||
<configuration> | |||
<appSettings> | |||
<add key="HKPlc_IP" value="107.107.2.17"/> | |||
<add key="Siemens_IP" value="107.107.2.200"/> | |||
<add key="HKPlc_Connect" value="false"/> | |||
<add key="Siemens_IP" value="107.107.2.200"/> | |||
<add key="MQTT_USERNAME" value="107.107.2.200"/> | |||
<add key="MQTT_PASSWORD" value="107.107.2.200"/> | |||
<add key="MQTT_IPADDRESS" value="107.107.2.200"/> | |||
<add key="MQTT_PORT" value="107.107.2.200"/> | |||
<add key="HKPlc_Connect" value="false"/> | |||
<add key="Siemens_Connect" value="false"/> | |||
</appSettings> | |||
</configuration> |
@@ -7,6 +7,9 @@ using System.Threading.Tasks; | |||
namespace BPASmartClient.JXJFoodBigStation.Model.HK_PLC | |||
{ | |||
/// <summary> | |||
/// 上位机只写的DB99。 | |||
/// </summary> | |||
public class DB_Write | |||
{ | |||
/// <summary> | |||
@@ -78,7 +78,6 @@ namespace BPASmartClient.JXJFoodBigStation.Model.HK_PLC | |||
{ | |||
int index = Array.FindIndex(recipe.RawMaterial.ToArray(), p => p.RawMaterialBarrelNum == barrel && p.RawMaterialLocation == loc); | |||
#region 新版本 | |||
int x = 0; | |||
if (barrel < 3) x = (barrel - 1) * 56 + 6; | |||
else if (barrel > 3) x = (barrel - 2) * 56 + 6; | |||
@@ -93,64 +92,6 @@ namespace BPASmartClient.JXJFoodBigStation.Model.HK_PLC | |||
HK_PLC_S7.Write(address, recipe.RawMaterial.ElementAt(index).RawMaterialWeight); | |||
MessageNotify.GetInstance.ShowRunLog($"配方编号:{recipe.RecipeCode},托盘编号:{recipe.TrayCode},桶号:{barrel},位置:{loc},重量:{recipe.RawMaterial.ElementAt(index).RawMaterialWeight}"); | |||
} | |||
#endregion | |||
#region 旧版本 | |||
//if (index == -1) | |||
//{ | |||
// switch (barrel) | |||
// { | |||
// case 1: | |||
// string address = "DB99.DBD" + (6 + 4 * (loc - 1)); | |||
// HK_PLC_S7.Write(address, 0); | |||
// break; | |||
// case 2: | |||
// string address1 = "DB99.DBD" + (62 + 4 * (loc - 1)); | |||
// HK_PLC_S7.Write(address1, 0); | |||
// break; | |||
// case 4: | |||
// string address2 = "DB99.DBD" + (118 + 4 * (loc - 1)); | |||
// HK_PLC_S7.Write(address2, 0); | |||
// break; | |||
// case 5: | |||
// string address3 = "DB99.DBD" + (174 + 4 * (loc - 1)); | |||
// HK_PLC_S7.Write(address3, 0); | |||
// break; | |||
// default: | |||
// break; | |||
// } | |||
//} | |||
//else | |||
//{ | |||
// switch (barrel) | |||
// { | |||
// case 1: | |||
// string address = "DB99.DBD" + (6 + 4 * (loc - 1)); | |||
// HK_PLC_S7.Write(address, recipe.RawMaterial.ElementAt(index).RawMaterialWeight); | |||
// MessageNotify.GetInstance.ShowRunLog($"配方编号:{recipe.RecipeCode},托盘编号:{recipe.TrayCode},桶号:{barrel},位置:{loc},重量:{recipe.RawMaterial.ElementAt(index).RawMaterialWeight}"); | |||
// break; | |||
// case 2: | |||
// string address1 = "DB99.DBD" + (62 + 4 * (loc - 1)); | |||
// HK_PLC_S7.Write(address1, recipe.RawMaterial.ElementAt(index).RawMaterialWeight); | |||
// MessageNotify.GetInstance.ShowRunLog($"配方编号:{recipe.RecipeCode},托盘编号:{recipe.TrayCode},桶号:{barrel},位置:{loc},重量:{recipe.RawMaterial.ElementAt(index).RawMaterialWeight}"); | |||
// break; | |||
// case 4: | |||
// string address2 = "DB99.DBD" + (118 + 4 * (loc - 1)); | |||
// HK_PLC_S7.Write(address2, recipe.RawMaterial.ElementAt(index).RawMaterialWeight); | |||
// MessageNotify.GetInstance.ShowRunLog($"配方编号:{recipe.RecipeCode},托盘编号:{recipe.TrayCode},桶号:{barrel},位置:{loc},重量:{recipe.RawMaterial.ElementAt(index).RawMaterialWeight}"); | |||
// break; | |||
// case 5: | |||
// string address3 = "DB99.DBD" + (174 + 4 * (loc - 1)); | |||
// HK_PLC_S7.Write(address3, recipe.RawMaterial.ElementAt(index).RawMaterialWeight); | |||
// MessageNotify.GetInstance.ShowRunLog($"配方编号:{recipe.RecipeCode},托盘编号:{recipe.TrayCode},桶号:{barrel},位置:{loc},重量:{recipe.RawMaterial.ElementAt(index).RawMaterialWeight}"); | |||
// break; | |||
// default: | |||
// break; | |||
// } | |||
//} | |||
#endregion | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,42 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.JXJFoodBigStation.Model.MQTT | |||
{ | |||
/// <summary> | |||
/// MQTT服务器接口。 | |||
/// </summary> | |||
public interface IMQTTServer | |||
{ | |||
#region 配料站-->服务 | |||
/// <summary> | |||
/// 请求取消订单。 | |||
/// </summary> | |||
/// <param name="recipecCode"></param> | |||
void PulishRequestCanelOrder(string recipecCode); | |||
/// <summary> | |||
/// 接收配方完成后反馈 | |||
/// </summary> | |||
void PublishReceiveRecipeFeedback(); | |||
/// <summary> | |||
/// 配方制作完成后反馈。 | |||
/// </summary> | |||
void PublishRecipeDosingFeedback(); | |||
#endregion | |||
#region 服务-->配料站 | |||
/// <summary> | |||
/// 下发配方 | |||
/// </summary> | |||
void GetIssueRecipeMessage(); | |||
/// <summary> | |||
/// 取消配方 | |||
/// </summary> | |||
void GetCancelOrderMessage(string recipeCode); | |||
#endregion | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.JXJFoodBigStation.Model.MQTT.Message | |||
{ | |||
public interface IMessage | |||
{ | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
using BPASmartClient.JXJFoodBigStation.Model.Siemens; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.JXJFoodBigStation.Model.MQTT.Message | |||
{ | |||
public class MessageDefine | |||
{ | |||
public readonly static Dictionary<int, Type> MSG = new Dictionary<int, Type>() | |||
{ | |||
{ MessageID.RecipeDosingFeedback,typeof(DL_Finish_DB)} | |||
}; | |||
} | |||
} |
@@ -0,0 +1,13 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.JXJFoodBigStation.Model.MQTT.Message | |||
{ | |||
public class MessageID | |||
{ | |||
public const int RecipeDosingFeedback = 1; | |||
} | |||
} |
@@ -0,0 +1,92 @@ | |||
using BPA.Helper; | |||
using Newtonsoft.Json.Linq; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.JXJFoodBigStation.Model.MQTT.Message | |||
{ | |||
public static class MsgPackExtensionMethod | |||
{ | |||
public static MsgPackage Deserialize(this string msg) | |||
{ | |||
if (msg != null) | |||
{ | |||
if (msg.Iskey("MessageId") && msg.Iskey("Message") && msg.Iskey("MessageLen")) | |||
{ | |||
var obj = msg.FromJSON<MsgPackage>(); | |||
if (obj != null) | |||
return obj; | |||
} | |||
else | |||
{ | |||
var id = msg.ToLower().GetJsonObjValue("messageid"); | |||
if (int.TryParse(id, out int tempId)) | |||
{ | |||
if (MessageDefine.MSG.ContainsKey(tempId)) | |||
{ | |||
MsgPackage package = new MsgPackage(); | |||
package.MessageId = tempId; | |||
if (int.TryParse(msg.ToLower().GetJsonObjValue("messagelen"), out int tempLen)) | |||
package.MessageLen = tempLen; | |||
var res = msg.ToLower().GetJsonObjValue("message"); | |||
if (res != null) | |||
{ | |||
package.Message = (IMessage)JsonConvert.DeserializeObject(res, MessageDefine.MSG[tempId]); | |||
} | |||
return package; | |||
} | |||
} | |||
} | |||
} | |||
return new MsgPackage(); | |||
} | |||
public static string Serialize(this IMessage mes) | |||
{ | |||
MsgPackage msg = new MsgPackage(); | |||
var res = MessageDefine.MSG.FirstOrDefault(p => p.Value == mes.GetType()); | |||
msg.MessageId = res.Key; | |||
msg.MessageLen = JsonConvert.SerializeObject(mes).Length; | |||
msg.Message = mes; | |||
return JsonConvert.SerializeObject(msg); | |||
} | |||
public static string GetJsonObjValue(this string input, string key) | |||
{ | |||
try | |||
{ | |||
JObject jo = (JObject)JsonConvert.DeserializeObject(input); | |||
if (jo != null && jo.ContainsKey(key)) | |||
return jo[key].ToString(); | |||
else | |||
return string.Empty; | |||
} | |||
catch (Exception EX) | |||
{ | |||
MessageLog.GetInstance.ShowEx(EX.ToString()); | |||
return string.Empty; | |||
} | |||
} | |||
public static bool Iskey(this string input, string key) | |||
{ | |||
try | |||
{ | |||
JObject jo = (JObject)JsonConvert.DeserializeObject(input); | |||
return jo != null && jo.ContainsKey(key); | |||
} | |||
catch (Exception EX) | |||
{ | |||
MessageLog.GetInstance.ShowEx(EX.ToString()); | |||
return false; | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.JXJFoodBigStation.Model.MQTT.Message | |||
{ | |||
public class MsgPackage | |||
{ | |||
/// <summary> | |||
/// 消息ID | |||
/// </summary> | |||
public int MessageId { get; set; } | |||
/// <summary> | |||
/// 消息内容 | |||
/// </summary> | |||
[JsonProperty(TypeNameHandling = TypeNameHandling.Auto)] | |||
public IMessage Message { get; set; } | |||
/// <summary> | |||
/// 消息长度 | |||
/// </summary> | |||
public int MessageLen { get; set; } | |||
} | |||
} |
@@ -0,0 +1,82 @@ | |||
using BPA.Communication; | |||
using BPA.Communication.Base; | |||
using BPA.Helper; | |||
using BPA.Message; | |||
using BPASmartClient.JXJFoodBigStation.Model.MQTT.Message; | |||
using BPASmartClient.JXJFoodBigStation.Model.Siemens; | |||
using Microsoft.EntityFrameworkCore.ChangeTracking; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Configuration; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.JXJFoodBigStation.Model.MQTT | |||
{ | |||
public class MqttServer | |||
{ | |||
private volatile static MqttServer _Instance; | |||
public static void Dis() => _Instance = null; | |||
public static MqttServer GetInstance => _Instance ?? (_Instance = new MqttServer()); | |||
private MqttServer() { } | |||
MqttHelper mqttHelper = new MqttHelper(); | |||
/// <summary> | |||
/// MQTT 消息 | |||
/// </summary> | |||
ConcurrentQueue<string> msg { get; set; } = new ConcurrentQueue<string>(); | |||
public Task Init(params object[] pars) | |||
{ | |||
return Task.Factory.StartNew(() => | |||
{ | |||
//mqttHelper.IsVerifyNetwork = false; | |||
mqttHelper.MessageRecive = new Action<string>(s => { msg.Enqueue(s); }); | |||
mqttHelper.Connected = new Action(() => | |||
{ | |||
if (pars.Length > 0) | |||
{ | |||
pars.ToList().ForEach(item => { mqttHelper.Subscrib(item?.ToString()); }); | |||
} | |||
else | |||
{ | |||
//订阅消息 | |||
} | |||
TaskManage.GetInstance.StartLong(new Action(() => | |||
{ | |||
while (msg.Count > 0) | |||
{ | |||
try | |||
{ | |||
if (msg.TryDequeue(out string str)) | |||
{ | |||
//解析消息 | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
MessageLog.GetInstance.ShowEx(ex.ToString()); | |||
} | |||
} | |||
Thread.Sleep(10); | |||
}), "MCS工单信息接收", true); | |||
}); | |||
mqttHelper.Connect(new ConfigurationOptions() | |||
{ | |||
UserName= ConfigurationManager.AppSettings["MQTT_USERNAME"], | |||
Password= ConfigurationManager.AppSettings["MQTT_PASSWORD"], | |||
IpAddress = ConfigurationManager.AppSettings["MQTT_IPADDRESS"], | |||
Port =Convert.ToInt32( ConfigurationManager.AppSettings["MQTT_PORT"]), | |||
ClientId = $"MES系统业务消息,{Guid.NewGuid()}" | |||
}); | |||
}); | |||
} | |||
} | |||
} |
@@ -0,0 +1,26 @@ | |||
namespace BPASmartClient.JXJFoodBigStation.Model.MQTT | |||
{ | |||
public sealed class Topic | |||
{ | |||
private const string Base = "jxjbaseuri"; | |||
/// <summary>下发配方</summary> | |||
public const string IssueRecipe = $"{Base}/issuerecipe"; | |||
/// <summary>接收配方反馈配方</summary> | |||
public const string ReceiveRecipeFeedback = $"{Base}/issuerecipe"; | |||
/// <summary> | |||
/// 请求取消订单 | |||
/// </summary> | |||
public const string RequestCancelOrder= $"{Base}/cancelorder"; | |||
/// <summary> | |||
/// 取消订单 | |||
/// </summary> | |||
public const string CancelOrder = $"{Base}/cancelorder"; | |||
/// <summary>配方完成信息反馈。</summary> | |||
public const string RecipeDosingFeedback = $"{Base}/cancelorder"; | |||
} | |||
} |
@@ -7,7 +7,7 @@ using System.Threading.Tasks; | |||
namespace BPASmartClient.JXJFoodBigStation.Model.Siemens | |||
{ | |||
public class DL_DataColl_DB | |||
public class DL_DataColl_DB | |||
{ | |||
[Siemens(16)] | |||
public string RecipeCode { get; set; } = ""; | |||
@@ -1,4 +1,5 @@ | |||
using BPASmartClient.S7Net; | |||
using BPASmartClient.JXJFoodBigStation.Model.MQTT.Message; | |||
using BPASmartClient.S7Net; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
@@ -322,7 +322,8 @@ | |||
Text="{Binding TrayCode}" /> | |||
</StackPanel> | |||
</StackPanel> | |||
<StackPanel Margin="0,8" Orientation="Horizontal"> | |||
<!--#region 后续修改不需要进行分类筛选了 --> | |||
<StackPanel Margin="0,8" Orientation="Horizontal" Visibility="Hidden"> | |||
<TextBlock | |||
Margin="10,0,5,0" | |||
VerticalAlignment="Center" | |||
@@ -343,6 +344,7 @@ | |||
ItemsSource="{Binding Categorys}" | |||
Text="{Binding RecipeCategory}" /> | |||
</StackPanel> | |||
<!--#endregion--> | |||
<Grid> | |||
<Grid.RowDefinitions> | |||
<RowDefinition /> | |||
@@ -293,7 +293,7 @@ | |||
FontSize="12" | |||
Foreground="#FF2AB2E7" | |||
Text="{Binding RecipeName}" /> | |||
<TextBlock | |||
<!--<TextBlock | |||
Grid.Row="5" | |||
Grid.Column="0" | |||
Margin="2,5,0,0" | |||
@@ -301,7 +301,7 @@ | |||
VerticalAlignment="Center" | |||
FontSize="12" | |||
Foreground="#FF2AB2E7" | |||
Text="配方类别:" /> | |||
Text="配方类别:" />--> | |||
@@ -62,6 +62,34 @@ namespace BPASmartClient.JXJFoodBigStation.ViewModel | |||
{ | |||
return; | |||
} | |||
if (string.IsNullOrWhiteSpace(RecipeName) ) | |||
{ | |||
MessageNotify.GetInstance.ShowDialog("配方名称不可为空,请修改后再试。",DialogType.Error); | |||
return; | |||
} | |||
if (TrayCode is <=0 or >5) | |||
{ | |||
MessageNotify.GetInstance.ShowDialog("请输入正确的托盘编号,请修改后再试。", DialogType.Error); | |||
return; | |||
} | |||
foreach (RawMaterial item in RawMaterialsInfo) | |||
{ | |||
if (item.RawMaterialLocation ==0) | |||
{ | |||
MessageNotify.GetInstance.ShowDialog("请输入正确的原料位置,请修改后再试。", DialogType.Error); | |||
return; | |||
} | |||
if (item.RawMaterialBarrelNum is <=0 or >4) | |||
{ | |||
MessageNotify.GetInstance.ShowDialog("请输入正确的托盘桶号,请修改后再试。", DialogType.Error); | |||
return; | |||
} | |||
if (item.RawMaterialWeight <=0) | |||
{ | |||
MessageNotify.GetInstance.ShowDialog("请输入正确的原料重量,请修改后再试。", DialogType.Error); | |||
return; | |||
} | |||
} | |||
var bom= Json<LocalRecipe>.Data.Recipes.FirstOrDefault(p => p.RecipeCode == RecipeCode); | |||
if (bom == null)//新配方 | |||
{ | |||
@@ -113,8 +113,8 @@ namespace BPASmartClient.JXJFoodBigStation.ViewModel | |||
} | |||
Json<LocalRecipe>.Data.Recipes.Clear(); | |||
Json<LocalRecipe>.Save(); | |||
Json<LocalRecipe>.Data.SelectedRecipes.Clear(); | |||
Json<LocalRecipe>.Save(); | |||
NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "成功", $"本地配方已全部删除!"); | |||
MessageNotify.GetInstance.ShowUserLog($"手动清除所有配方。"); | |||
}); | |||
@@ -126,6 +126,11 @@ namespace BPASmartClient.JXJFoodBigStation.ViewModel | |||
return; | |||
} | |||
var res = Recipes.FirstOrDefault(p => p.RecipeCode == recipeCode); | |||
var res1 = Json<LocalRecipe>.Data.SelectedRecipes.FirstOrDefault(p => p.RecipeCode == recipeCode); | |||
if (res1 is not null) | |||
{ | |||
Json<LocalRecipe>.Data.SelectedRecipes.Remove(res1); | |||
} | |||
if (res != null) | |||
{ | |||
Recipes.Remove(res); | |||
@@ -17,6 +17,7 @@ namespace BPASmartClient.JXJFoodBigStation.ViewModel | |||
public SelectRecipesViewModel() | |||
{ | |||
AllRecipes = new(); | |||
SelectRecipes.Clear(); | |||
foreach (var item in Json<LocalRecipe>.Data.SelectedRecipes) | |||
{ | |||
SelectRecipes.Add(item); | |||
@@ -57,15 +57,15 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
/// </summary> | |||
public ushort StockBinCylinderStatus { get; set; } | |||
[VarComm("Global", "柔性配料料仓配料下发情况")] | |||
/// <summary> | |||
/// 料仓配料情况 | |||
/// </summary> | |||
public ushort[] StockBinDosingIssue { get; set; } = new ushort[5] { 0, 0, 0, 0, 0 }; | |||
[VarComm("Global", "柔性配料料仓配料下发情况")] | |||
public ushort[] StockBinDosingIssue { get; set; } = new ushort[5] { 0, 0, 0, 0, 0 }; | |||
/// <summary> | |||
/// 料仓配料情况 | |||
/// </summary> | |||
[VarComm("Global", "柔性配料料仓配料下发情况")] | |||
public ushort[] RecipeStockBinDosing { get; set; } = new ushort[5] { 0, 0, 0, 0, 0 }; | |||
[VarComm("Global", "柔性配料料仓配料情况")] | |||
@@ -92,163 +92,161 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
/// </summary> | |||
public int Tray2LogicFinish { get; set; } = 0; | |||
[VarComm("Global", "托盘1有货架")] | |||
/// <summary> | |||
/// 托盘1有货架 | |||
/// </summary> | |||
[VarComm("Global", "托盘1有货架")] | |||
public bool Station1HaveTray { get; set; } | |||
[VarComm("Global", "托盘2有货架")] | |||
/// <summary> | |||
/// 托盘2有货架 | |||
/// </summary> | |||
[VarComm("Global", "托盘2有货架")] | |||
public bool Station2HaveTray { get; set; } | |||
[VarComm("Global", "托盘1传感器信号")] | |||
/// <summary> | |||
/// 托盘1传感器信号 | |||
/// </summary> | |||
[VarComm("Global", "托盘1传感器信号")] | |||
public bool Station1Sensor { get; set; } | |||
[VarComm("Global", "托盘2传感器信号")] | |||
/// <summary> | |||
/// 托盘2传感器信号 | |||
/// </summary> | |||
[VarComm("Global", "托盘2传感器信号")] | |||
public bool Station2Sensor { get; set; } | |||
[VarComm("Global", "托盘1气缸信号")] | |||
/// <summary> | |||
/// 托盘1气缸信号 | |||
/// </summary> | |||
[VarComm("Global", "托盘1气缸信号")] | |||
public bool Station1Cylinder { get; set; } | |||
[VarComm("Global", "托盘2气缸信号")] | |||
/// <summary> | |||
/// 托盘2气缸信号 | |||
/// </summary> | |||
[VarComm("Global", "托盘2气缸信号")] | |||
public bool Station2Cylinder { get; set; } | |||
[VarComm("Global", "AGV放托盘1完成")] | |||
/// <summary> | |||
/// AGV放托盘1完成 | |||
/// </summary> | |||
[VarComm("Global", "AGV放托盘1完成")] | |||
public bool AGV_PutTray1Finish { get; set; } | |||
[VarComm("Global", "AGV取托盘1完成")] | |||
/// <summary> | |||
/// AGV取托盘1完成 | |||
/// </summary> | |||
[VarComm("Global", "AGV取托盘1完成")] | |||
public bool AGV_GetTray1Finish { get; set; } | |||
[VarComm("Global", "AGV放托盘2完成")] | |||
/// <summary> | |||
/// AGV放托盘1完成 | |||
/// </summary> | |||
[VarComm("Global", "AGV放托盘2完成")] | |||
public bool AGV_PutTray2Finish { get; set; } | |||
[VarComm("Global", "AGV取托盘2完成")] | |||
/// <summary> | |||
/// AGV取托盘2完成 | |||
/// </summary> | |||
[VarComm("Global", "AGV取托盘2完成")] | |||
public bool AGV_GetTray2Finish { get; set; } | |||
[VarComm("Global", "托盘1气缸复位")] | |||
/// <summary> | |||
/// 托盘1气缸复位 | |||
/// </summary> | |||
[VarComm("Global", "托盘1气缸复位")] | |||
public bool CylinderReset { get; set; } | |||
[VarComm("Global", "发送给plc的心跳")] | |||
/// <summary> | |||
/// 发送给plc的心跳 | |||
/// </summary> | |||
[VarComm("Global", "发送给plc的心跳")] | |||
public bool HeartBeatToPlc { get; set; } = false; | |||
[VarComm("Global", "屏蔽小料站料仓不足15个报警")] | |||
public bool DisEnableStockAlarm { get; set; } = false; | |||
[VarComm("Global", "配方制作完成数量")] | |||
/// <summary> | |||
/// 配方制作完成数量 | |||
/// </summary> | |||
[VarComm("Global", "配方制作完成数量")] | |||
public int RecipeDosingCompleNum { get; set; } = 0; | |||
[VarComm("Global", "来自plc的心跳")] | |||
/// <summary> | |||
/// 来自plc的心跳 | |||
/// </summary> | |||
[VarComm("Global", "来自plc的心跳")] | |||
public bool HeartBeatFromPlc { get; set; } = false; | |||
[VarComm("Global", "是否允许西门子下发配方")] | |||
/// <summary> | |||
/// 是否允许西门子下发配方 | |||
/// </summary> | |||
[VarComm("Global", "是否允许西门子下发配方")] | |||
public bool IsAllowSiemensSendRecipe { get; set; } = false; | |||
[VarComm("Global", "西门子下发配方状态0=等待下发配方 1=请求下发配方 2=接收配方 3=配方接收配方完成 4=请求配料 5=西门子确认开始配料 6=西门子确认开始配料信号复位")] | |||
/// <summary> | |||
/// 西门子下发配方状态 0:等待下发配方 1:请求下发配方 2:上位机接收配方 3:配方接收配方完成 4:上位机向西门子请求配料 5:西门子确认开始配料 6:西门子确认开始配料 信号复位 | |||
/// </summary> | |||
[VarComm("Global", "西门子下发配方状态0=等待下发配方 1=请求下发配方 2=接收配方 3=配方接收配方完成 4=请求配料 5=西门子确认开始配料 6=西门子确认开始配料信号复位")] | |||
public int SiemensSendRecipeStatus { get; set; } = 0; | |||
[VarComm("Global", "配方1下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料")] | |||
/// <summary> | |||
/// 配方下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料 | |||
/// </summary> | |||
[VarComm("Global", "配方1下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料")] | |||
public int RecipeStatusIDTray1 { get; set; } = 0; | |||
[VarComm("Global", "配方1下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料")] | |||
/// <summary> | |||
/// 配方下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料 | |||
/// </summary> | |||
[VarComm("Global", "配方1下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料")] | |||
public int[] RecipeProcessStatus { get; set; } = new int[5] { 0, 0, 0, 0, 0 }; | |||
[VarComm("Global", "配方1下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料")] | |||
/// <summary> | |||
/// 配方下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料 | |||
/// </summary> | |||
[VarComm("Global", "配方1下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料")] | |||
public bool AGVIsGetTray { get; set; } = false; | |||
[VarComm("Global", "配方2下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料")] | |||
/// <summary> | |||
/// 配方下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料 | |||
/// </summary> | |||
[VarComm("Global", "配方2下发状态 =0:配方未下发 ,1:配方下发给plc ,2:plc成功接收配方,正在配料")] | |||
public int RecipeStatusIDTray2 { get; set; } = 0; | |||
[VarComm("Global", "当前配方正在配料位置")] | |||
/// <summary> | |||
/// 当前料仓的位置 | |||
/// </summary> | |||
[VarComm("Global", "当前配方正在配料位置")] | |||
public int StockInIsWork { get; set; } = 0; | |||
[VarComm("Global", "设置料仓配料完成")] | |||
/// <summary> | |||
/// 当前料仓的位置 | |||
/// </summary> | |||
[VarComm("Global", "设置料仓配料完成")] | |||
public bool[] StockInDosingComple { get; set; } = new bool[15]; | |||
[VarComm("Global", "是否使用粉仓配料")] | |||
/// <summary> | |||
/// 是否使用粉仓配料 | |||
/// </summary> | |||
[VarComm("Global", "是否使用粉仓配料")] | |||
public bool IsUseWindSend { get; set; } = false; | |||
[VarComm("Global", "粉仓正在配料")] | |||
/// <summary> | |||
/// 粉仓正在配料 | |||
/// </summary> | |||
[VarComm("Global", "粉仓正在配料")] | |||
public bool WindSendDosing { get; set; } = false; | |||
@@ -259,16 +257,17 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
#region 本地模拟配方 | |||
[VarComm("Global", "是否使用本地模拟配方")] | |||
/// <summary> | |||
/// 是否使用本地模拟配方 | |||
/// </summary> | |||
[VarComm("Global", "是否使用本地模拟配方")] | |||
public bool IsUseLocalRecipe { get; set; } | |||
[VarComm("Global", "是否使用本地模拟配方")] | |||
/// <summary> | |||
/// 是否使用本地模拟配方 | |||
/// 不使用小料站配料 | |||
/// </summary> | |||
[VarComm("Global", "是否使用本地模拟配方")] | |||
public bool NotUseSmallStation { get; set; } | |||
/// <summary> | |||
@@ -299,16 +298,16 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
public bool WindSendDosingComple { get; set; } = false; | |||
[VarComm("Global", "粉料仓配料状态")] | |||
/// <summary> | |||
/// 粉料仓配料状态(0:无意义,1:粉料仓下配方,2:plc接收配方完成,3:粉料仓配料完成,4:粉料仓配料完成信号复位,5:排料完成) | |||
/// </summary> | |||
[VarComm("Global", "粉料仓配料状态")] | |||
public int WindSendDosingStatus { get; set; } = 0; | |||
[VarComm("Global", "PLC的系统模式 DB44.DBX0.1")] | |||
/// <summary> | |||
/// PLC的系统模式 DB44.DBX0.1 | |||
/// </summary> | |||
[VarComm("Global", "PLC的系统模式 DB44.DBX0.1")] | |||
public bool PlcSystemMode { get; set; } = false; | |||
[VarComm("Global", "PLC的系统模式 DB44.DBX0.1")] | |||
@@ -41,21 +41,21 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
/// <summary> | |||
/// 物料集合 | |||
/// 物料集合(工位配方集合,五个键分别对应五个工位) | |||
/// </summary> | |||
public Dictionary<int, ConcurrentQueue<string>> RecipeQueueTray { get; set; } = new Dictionary<int, ConcurrentQueue<string>>(); | |||
public ConcurrentQueue<string> RecipeQueueTray2 = new ConcurrentQueue<string>(); | |||
public SiemensDeviceStatus SiemensDevice = new SiemensDeviceStatus(); | |||
//XL_Finish_DB RecipeFinishInfo = new XL_Finish_DB(); | |||
//public SiemensDeviceStatus SiemensDevice = new SiemensDeviceStatus(); | |||
public HKDeviceStatus HKDevice = new HKDeviceStatus(); | |||
public WindSendDeviceStatus WindSendDevice = new WindSendDeviceStatus(); | |||
public ObservableCollection<PlcInfos> CommData { get; set; } = new ObservableCollection<PlcInfos>(); | |||
public ObservableCollection<PlcInfos> ProcessVar { get; set; } = new ObservableCollection<PlcInfos>(); | |||
XL_Finish_DB RecipeFinishInfo = new XL_Finish_DB(); | |||
/// <summary> | |||
/// 风送PLC的DB块 | |||
/// </summary> | |||
@@ -333,8 +333,8 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
GVL_SmallStation.GetInstance.RobotStatus = HKDevice.HK_PLC_S7.Read<byte>("DB3.DBB0"); | |||
GVL_SmallStation.GetInstance.RobotProgramNum = HKDevice.HK_PLC_S7.Read<byte>("DB3.DBB1"); | |||
} | |||
if (SiemensDevice.IsConnected) | |||
{ | |||
//if (SiemensDevice.IsConnected) | |||
//{ | |||
ushort TrayCylinder = 0; | |||
ushort TraySensor = 0; | |||
if (GVL_SmallStation.GetInstance.Station1Sensor) | |||
@@ -353,10 +353,10 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
{ | |||
TrayCylinder = TrayCylinder.SetBitValue(0, false); | |||
} | |||
this.SiemensDevice.Siemens_PLC_S7.Write<bool>("DB2231.DBX28.4", GVL_SmallStation.GetInstance.WindSendAllowAGVPutGet); | |||
this.SiemensDevice.Siemens_PLC_S7.Write<ushort>("DB2231.DBW190", TraySensor);//添加工位传感器的信号 | |||
this.SiemensDevice.Siemens_PLC_S7.Write<ushort>("DB2231.DBW192", TrayCylinder);//添加工位气缸的信号 | |||
ushort AGV_Put = (ushort)SiemensDevice.XL_Status.AgvFinishPut; | |||
//this.SiemensDevice.Siemens_PLC_S7.Write<bool>("DB2231.DBX28.4", GVL_SmallStation.GetInstance.WindSendAllowAGVPutGet); | |||
//this.SiemensDevice.Siemens_PLC_S7.Write<ushort>("DB2231.DBW190", TraySensor);//添加工位传感器的信号 | |||
//this.SiemensDevice.Siemens_PLC_S7.Write<ushort>("DB2231.DBW192", TrayCylinder);//添加工位气缸的信号 | |||
ushort AGV_Put =0 /*(ushort)SiemensDevice.XL_Status.AgvFinishPut*/; | |||
if (AGV_Put.GetBitValue(1)) | |||
{ | |||
GVL_SmallStation.GetInstance.AGV_PutTray1Finish = true; | |||
@@ -365,7 +365,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
{ | |||
GVL_SmallStation.GetInstance.AGV_PutTray1Finish = false; | |||
} | |||
ushort AGV_Get = (ushort)SiemensDevice.XL_Status.AgvFinishGet; | |||
ushort AGV_Get =0/* (ushort)SiemensDevice.XL_Status.AgvFinishGet*/; | |||
if (AGV_Get.GetBitValue(1)) | |||
{ | |||
GVL_SmallStation.GetInstance.AGV_GetTray1Finish = true; | |||
@@ -374,7 +374,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
{ | |||
GVL_SmallStation.GetInstance.AGV_GetTray1Finish = false; | |||
} | |||
} | |||
//} | |||
} | |||
public void CancelOrder() | |||
@@ -442,16 +442,16 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
} | |||
break; | |||
case 3: | |||
SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", true); | |||
//SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", true); | |||
GVL_SmallStation.GetInstance.OrderCancelStep = 4; | |||
break; | |||
case 4: | |||
if (SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2201.DBX440.1") == false) | |||
{ | |||
SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", false); | |||
//if (SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2201.DBX440.1") == false) | |||
//{ | |||
// SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", false); | |||
GVL_SmallStation.GetInstance.OrderCancelStep = 9; | |||
MessageNotify.GetInstance.ShowRunLog($"队列1,西门子取消订单完成,订单号:{code}"); | |||
} | |||
//} | |||
break; | |||
case 9: | |||
App.Current.Dispatcher.Invoke(() => | |||
@@ -465,16 +465,16 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
GVL_SmallStation.GetInstance.OrderCancelStep = 0; | |||
break; | |||
case 20: | |||
SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", true); | |||
//SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", true); | |||
GVL_SmallStation.GetInstance.OrderCancelStep = 21; | |||
break; | |||
case 21: | |||
if (SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2201.DBX440.1") == false) | |||
{ | |||
SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", false); | |||
//if (SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2201.DBX440.1") == false) | |||
//{ | |||
// SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", false); | |||
GVL_SmallStation.GetInstance.OrderCancelStep = 29; | |||
MessageNotify.GetInstance.ShowRunLog($"队列1,西门子取消订单完成,订单号:{code}"); | |||
} | |||
//} | |||
break; | |||
case 29: | |||
App.Current.Dispatcher.Invoke(() => | |||
@@ -489,16 +489,16 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
//30-39为订单还未下发至上位机 | |||
case 30: | |||
SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", true); | |||
//SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", true); | |||
GVL_SmallStation.GetInstance.OrderCancelStep = 31; | |||
break; | |||
case 31: | |||
if (SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2201.DBX440.1") == false) | |||
{ | |||
SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", false); | |||
//if (SiemensDevice.Siemens_PLC_S7.Read<bool>("DB2201.DBX440.1") == false) | |||
//{ | |||
// SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", false); | |||
GVL_SmallStation.GetInstance.OrderCancelStep = 39; | |||
MessageNotify.GetInstance.ShowRunLog($"西门子取消订单完成,订单号:{code}"); | |||
} | |||
//} | |||
break; | |||
case 39: | |||
GVL_SmallStation.GetInstance.Order_Cancel = false; | |||
@@ -521,33 +521,33 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
{ | |||
foreach (var data in RemoteRecipes) | |||
{ | |||
if (data.TrayCode == 1) | |||
{ | |||
if (SiemensDevice.XL_Status is XL_Status_DB status) | |||
{ | |||
//if (data.TrayCode == 1) | |||
//{ | |||
//if (SiemensDevice.XL_Status is XL_Status_DB status) | |||
//{ | |||
switch (GVL_SmallStation.GetInstance.SiemensSendRecipeStatus) | |||
{ | |||
case 3: | |||
SiemensDevice.Siemens_PLC_S7.WriteString(2231, data.RecipeCode, 10); | |||
SiemensDevice.Siemens_PLC_S7.Write("DB2231.DBX28.0", true); | |||
// SiemensDevice.Siemens_PLC_S7.WriteString(2231, data.RecipeCode, 10); | |||
//SiemensDevice.Siemens_PLC_S7.Write("DB2231.DBX28.0", true); | |||
GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 4; | |||
MessageNotify.GetInstance.ShowRunLog($"配方{data.RecipeCode},请求配料"); | |||
break; | |||
case 4: | |||
if (SiemensDevice.XL_Status.Dosing_Confirm) | |||
{ | |||
SiemensDevice.Siemens_PLC_S7.WriteString(2231, "", 10);//复位字符串 | |||
SiemensDevice.Siemens_PLC_S7.Write("DB2231.DBX28.0", false); | |||
//if (SiemensDevice.XL_Status.Dosing_Confirm) | |||
//{ | |||
// SiemensDevice.Siemens_PLC_S7.WriteString(2231, "", 10);//复位字符串 | |||
// SiemensDevice.Siemens_PLC_S7.Write("DB2231.DBX28.0", false); | |||
GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 5; | |||
MessageNotify.GetInstance.ShowRunLog($"配方{data.RecipeCode},西门子确认配料"); | |||
} | |||
// } | |||
break; | |||
case 5: | |||
if (SiemensDevice.XL_Status.Dosing_Confirm == false) | |||
{ | |||
//if (SiemensDevice.XL_Status.Dosing_Confirm == false) | |||
//{ | |||
GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 6; | |||
MessageNotify.GetInstance.ShowRunLog($"配方{data.RecipeCode},西门子确认配料信号复位完成"); | |||
} | |||
//} | |||
break; | |||
case 6: | |||
for (int i = 0; i < 5; i++) | |||
@@ -574,10 +574,10 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
break; | |||
default: | |||
break; | |||
} | |||
//} | |||
} | |||
} | |||
//} | |||
} | |||
} | |||
else | |||
@@ -598,8 +598,8 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
{ | |||
foreach (var data in RemoteRecipes) | |||
{ | |||
if (data.TrayCode == 1) | |||
{ | |||
//if (data.TrayCode == 1) | |||
//{ | |||
for (int i = 0; i < 5; i++) | |||
{ | |||
if (GVL_SmallStation.GetInstance.NotUseSmallStation) | |||
@@ -619,7 +619,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
} | |||
} | |||
} | |||
} | |||
//} | |||
} | |||
} | |||
else | |||
@@ -639,6 +639,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
/// </summary> | |||
private void RecipeInfoToHKPLC() | |||
{ | |||
//五个工位AGV控制请求流程。 | |||
if (!GVL_SmallStation.GetInstance.NotUseSmallStation) | |||
{ | |||
for (int i = 0; i < 5; i++) | |||
@@ -657,7 +658,6 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
break; | |||
case 1: | |||
if (GVL_SmallStation.GetInstance.Station1HaveTray) | |||
{ | |||
HKDevice.HK_PLC_S7.Write("DB4.DBX8." + i, false); | |||
GVL_SmallStation.GetInstance.Tray_AGVLogic[i] = 2; | |||
@@ -688,11 +688,16 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
} | |||
} | |||
} | |||
//工位配料流程 | |||
foreach (var recipe in RecipeQueueTray) | |||
{ | |||
//recipeNum就是托盘号,也就是工位号。 | |||
int recipeNum = recipe.Key; | |||
//判断工位是否有配方。 | |||
if (RecipeQueueTray[recipeNum].Count > 0) | |||
{ | |||
//从配方列表里根据配方号查找配方 | |||
int index = Array.FindIndex(RemoteRecipes.ToArray(), p => p.RecipeCode == RecipeQueueTray[recipeNum].ElementAt(0)); | |||
if (index >= 0 && index < RemoteRecipes.Count) | |||
{ | |||
@@ -700,44 +705,46 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
int trayCode = RemoteRecipes.ElementAt(index).TrayCode; | |||
string recipeName = RemoteRecipes.ElementAt(index).RecipeName; | |||
string windSend = RemoteRecipes.ElementAt(index).ToString(); | |||
//当前只配托盘号为1 ,即工位1 的配方。 | |||
if (trayCode == 1) | |||
{ | |||
//如果不使用小料站配料,目前没有这种工作情况。 | |||
if (GVL_SmallStation.GetInstance.NotUseSmallStation) | |||
{ | |||
if (GVL_SmallStation.GetInstance.AGV_PutTray1Finish) | |||
{ | |||
Thread.Sleep(5000); | |||
var res = Json<RemoteRecipeDataColl>.Data.Recipes.FirstOrDefault(p => p.RecipeCode == code); | |||
if (SiemensDevice.IsConnected && !GVL_SmallStation.GetInstance.IsUseLocalRecipe) | |||
{ | |||
RecipeFinishInfo.Order_No = RemoteRecipes.ElementAt(index).RecipeCode; | |||
RecipeFinishInfo.Product_Code = RemoteRecipes.ElementAt(index).RecipeName; | |||
RecipeFinishInfo.Job_No = (short)trayCode; | |||
for (int i = 0; i < 20; i++) | |||
{ | |||
RecipeFinishInfo.Material[i] = new UDT1(); | |||
} | |||
for (int i = 0; i < 10; i++) | |||
{ | |||
RecipeFinishInfo.Powder[i] = new UDT2(); | |||
} | |||
for (int i = 0; i < RemoteRecipes.ElementAt(index).RawMaterial.Count; i++) | |||
{ | |||
RecipeFinishInfo.Material[i].Material_Name = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialName; | |||
RecipeFinishInfo.Material[i].Material_BarrelNum = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialBarrelNum; | |||
RecipeFinishInfo.Material[i].Material_Laying_Off_Weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).Laying_Off_Weight * (float)0.001; | |||
} | |||
for (int i = 0; i < RemoteRecipes.ElementAt(index).WindSend.Count; i++) | |||
{ | |||
RecipeFinishInfo.Powder[i].Powder_Weight = RemoteRecipes.ElementAt(index).WindSend.ElementAt(i).DosingCompleWeight; | |||
} | |||
RecipeFinishInfo.Ask_For_Finish = true; | |||
RecipeFinishInfo.DosingTime = Convert.ToInt16(0); | |||
SiemensDevice.Siemens_PLC_S7.WriteClass<XL_Finish_DB>(RecipeFinishInfo, 2261); | |||
//if (SiemensDevice.IsConnected && !GVL_SmallStation.GetInstance.IsUseLocalRecipe) | |||
//{ | |||
// RecipeFinishInfo.Order_No = RemoteRecipes.ElementAt(index).RecipeCode; | |||
// RecipeFinishInfo.Product_Code = RemoteRecipes.ElementAt(index).RecipeName; | |||
// RecipeFinishInfo.Job_No = (short)trayCode; | |||
// for (int i = 0; i < 20; i++) | |||
// { | |||
// RecipeFinishInfo.Material[i] = new UDT1(); | |||
// } | |||
// for (int i = 0; i < 10; i++) | |||
// { | |||
// RecipeFinishInfo.Powder[i] = new UDT2(); | |||
// } | |||
// for (int i = 0; i < RemoteRecipes.ElementAt(index).RawMaterial.Count; i++) | |||
// { | |||
// RecipeFinishInfo.Material[i].Material_Name = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialName; | |||
// RecipeFinishInfo.Material[i].Material_BarrelNum = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialBarrelNum; | |||
// RecipeFinishInfo.Material[i].Material_Laying_Off_Weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).Laying_Off_Weight * (float)0.001; | |||
// } | |||
// for (int i = 0; i < RemoteRecipes.ElementAt(index).WindSend.Count; i++) | |||
// { | |||
// RecipeFinishInfo.Powder[i].Powder_Weight = RemoteRecipes.ElementAt(index).WindSend.ElementAt(i).DosingCompleWeight; | |||
// } | |||
// RecipeFinishInfo.Ask_For_Finish = true; | |||
// RecipeFinishInfo.DosingTime = Convert.ToInt16(0); | |||
// SiemensDevice.Siemens_PLC_S7.WriteClass<XL_Finish_DB>(RecipeFinishInfo, 2261); | |||
MessageNotify.GetInstance.ShowRunLog($"托盘1,配方{res.RecipeName},配料完成,数据反馈给西门子"); | |||
} | |||
else | |||
// MessageNotify.GetInstance.ShowRunLog($"托盘1,配方{res.RecipeName},配料完成,数据反馈给西门子"); | |||
//} | |||
//else | |||
{ | |||
MessageNotify.GetInstance.ShowRunLog($"托盘1,配方{res.RecipeName},配料完成,数据无法反馈给西门子,西门子设备未连接或处于本地配方"); | |||
} | |||
@@ -760,9 +767,11 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
{ | |||
if (GVL_SmallStation.GetInstance.WindSendDosingStatus == 1) | |||
{ | |||
//清空风送配料数据 | |||
WindSend_Write WindSendData111 = new WindSend_Write(); | |||
WindSendDevice.Siemens_PLC_S7.WriteClass<WindSend_Write>(WindSendData111, 95); | |||
Thread.Sleep(200); | |||
//设置DB95数据并下发。 | |||
WindSendData111.TargetRecipeCode = code; | |||
WindSendData111.IsAllowDosing = true; | |||
foreach (var item in RemoteRecipes.ElementAt(index).WindSend) | |||
@@ -795,6 +804,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
} | |||
GVL_SmallStation.GetInstance.WindSendDosing = true; | |||
GVL_SmallStation.GetInstance.WindSendDosingStatus = 2; | |||
//下发配料数据 | |||
WindSendDevice.Siemens_PLC_S7.WriteClass<WindSend_Write>(WindSendData111, 95); | |||
} | |||
} | |||
@@ -807,30 +817,39 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
} | |||
} | |||
} | |||
//如果小料仓配方下发状态为0(未下发),则下发配方。并清除该工位配方的配料情况信号。 | |||
if (GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] == 0) | |||
{ | |||
GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] = 0; | |||
//下发工单,并置位工单下发确认。 | |||
HKDevice.IssueRecipeToPlc(RemoteRecipes.ElementAt(index).RawMaterial, recipeNum); | |||
HKDevice.HK_PLC_S7.Write("DB4.DBX2." + recipeNum, true); | |||
//下发完成,等待开始制作。 | |||
GVL_SmallStation.GetInstance.DosingTime[recipeNum] = DateTime.Now; | |||
GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 1; | |||
MessageNotify.GetInstance.ShowRunLog($"托盘1,配方编号{code},配方号{recipeNum + 1},下发完成"); | |||
} | |||
//确认是否收到工单 | |||
bool recipeReceviceFinish = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX4." + recipeNum); | |||
if (recipeReceviceFinish && GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] == 1) | |||
{ | |||
//确认PLC收到工单后,复位下发确认信号。 | |||
HKDevice.HK_PLC_S7.Write("DB4.DBX2." + recipeNum, false); | |||
GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 2; | |||
GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] = 0; | |||
MessageNotify.GetInstance.ShowRunLog($"托盘1,配方编号{code},配方号{recipeNum + 1},配方接收完成"); | |||
} | |||
//粉料仓完毕,开始控制小料仓味魔方配料。 | |||
if (GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] == 2) | |||
{ | |||
//味魔方配料。 | |||
for (byte i = 1; i < 16; i++) | |||
{ | |||
//indexArr是各配方位置反馈。 | |||
int indexArr = -1; | |||
if (GVL_SmallStation.GetInstance.plcReadDataDB3.StockBinAllowIssue[i - 1]) | |||
{ | |||
//根据配方号查找各配方的三个桶的位置反馈。位置反馈用的是ushort转16位2进制表示。 | |||
switch (recipeNum) | |||
{ | |||
case 0: | |||
@@ -849,10 +868,12 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
indexArr = Array.FindIndex(GVL_SmallStation.GetInstance.plcReadDataDB3.Recipe5BarrelPosReserve.ToArray(), p => p == i); | |||
break; | |||
} | |||
//如果料桶已经到位但没有配料完成信号。 | |||
if (indexArr >= 0 && GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum].GetBitValue((byte)i) == false) | |||
{ | |||
int loc_index = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == i); | |||
float weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(loc_index).RawMaterialWeight * 1000;//单位g转换kg | |||
//如果重量为0,即不需要配料。则直接设为配料完成。 | |||
if (weight <= 0) | |||
{ | |||
if (i >= 1 && i <= 8) | |||
@@ -870,6 +891,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
} | |||
else | |||
{ | |||
//下发小料仓味魔方配料指令。 | |||
if (loc_index >= 0) | |||
{ | |||
DeviceInquire.GetInstance.GetDevice((int)i)?.Start(weight);//根据料仓编号 启动并写入每个原料重量 | |||
@@ -886,6 +908,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
{ | |||
//MessageNotify.GetInstance.ShowRunLog($"错误,有允许配料信号,但没有相应的位置 和桶号"); | |||
} | |||
//味魔方配料完成后处理。 | |||
if ((DeviceInquire.GetInstance.GetDevice(i).deviceStatus.RunStatus == 3) && indexArr >= 0 && GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum].GetBitValue((byte)i)) | |||
{ | |||
int res = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == i); | |||
@@ -895,10 +918,15 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
} | |||
else | |||
{ | |||
//配料完成后,先延时一段时间再复位。 | |||
Thread.Sleep(GVL_SmallStation.GetInstance.Time); | |||
//获取实际下料重量后复位配料完成状态。 | |||
RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight = DeviceInquire.GetInstance.GetDevice(i).deviceStatus.NowWeightFeedback; | |||
bool info = DeviceInquire.GetInstance.GetDevice(i).StatusReset(); | |||
MessageNotify.GetInstance.ShowRunLog($"柔性味魔方,托盘1,配方:{recipeName},{i}号仓,配料完成,下料完成重量:{RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight}"); | |||
//计算误差范围是否在允许范围内,如果超出范围,则报警。 | |||
float AlarmRange = Math.Abs(RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight - RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).RawMaterialWeight * 1000); | |||
int iIndex = Array.FindIndex(Json<DevicePar>.Data.deviceParModels.ToArray(), p => p.MaterialName == DeviceInquire.GetInstance.GetDevice(i).DeviceName); | |||
if (iIndex >= 0) | |||
@@ -913,6 +941,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
}); | |||
} | |||
} | |||
//置位味魔方配料完成信号。 | |||
if (i >= 1 && i <= 8) | |||
{ | |||
string commInfo = HKDevice.HK_PLC_S7.Write("DB4.DBX12." + (i - 1), true); | |||
@@ -929,6 +958,8 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
} | |||
} | |||
} | |||
//接收到工单配料完成上升沿后。 | |||
bool DosingComple = HKDevice.HK_PLC_S7.Read<bool>("DB3.DBX6." + recipeNum); | |||
if ((RTrig.GetInstance("配方配料完成").Start(DosingComple)) || (GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] > 0 && DosingComple)) | |||
{ | |||
@@ -937,7 +968,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
if (GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] > 0) | |||
{ | |||
for (int i = 1; i < 17; i++) | |||
{ | |||
{//看不懂 | |||
if (GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum].GetBitValue((byte)i)) | |||
{ | |||
MessageNotify.GetInstance.ShowRunLog($"料仓配料完成,但存在料仓未配料:{i}号仓"); | |||
@@ -950,37 +981,37 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
{ | |||
MessageNotify.GetInstance.ShowRunLog($"{item.RawMaterialName},下料重量:{item.Laying_Off_Weight}g"); | |||
} | |||
if (SiemensDevice.IsConnected && !GVL_SmallStation.GetInstance.IsUseLocalRecipe) | |||
{ | |||
RecipeFinishInfo.Order_No = RemoteRecipes.ElementAt(index).RecipeCode; | |||
RecipeFinishInfo.Product_Code = RemoteRecipes.ElementAt(index).RecipeName; | |||
RecipeFinishInfo.Job_No = (short)trayCode; | |||
for (int i = 0; i < 20; i++) | |||
{ | |||
RecipeFinishInfo.Material[i] = new UDT1(); | |||
} | |||
for (int i = 0; i < 10; i++) | |||
{ | |||
RecipeFinishInfo.Powder[i] = new UDT2(); | |||
} | |||
for (int i = 0; i < RemoteRecipes.ElementAt(index).RawMaterial.Count; i++) | |||
{ | |||
RecipeFinishInfo.Material[i].Material_Name = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialName; | |||
RecipeFinishInfo.Material[i].Material_BarrelNum = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialBarrelNum; | |||
RecipeFinishInfo.Material[i].Material_Laying_Off_Weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).Laying_Off_Weight * (float)0.001; | |||
} | |||
for (int i = 0; i < RemoteRecipes.ElementAt(index).WindSend.Count; i++) | |||
{ | |||
RecipeFinishInfo.Powder[i].Powder_Weight = RemoteRecipes.ElementAt(index).WindSend.ElementAt(i).DosingCompleWeight; | |||
} | |||
RecipeFinishInfo.Ask_For_Finish = true; | |||
RecipeFinishInfo.DosingTime = Convert.ToInt16(a); | |||
SiemensDevice.Siemens_PLC_S7.WriteClass<XL_Finish_DB>(RecipeFinishInfo, 2261); | |||
//if (SiemensDevice.IsConnected && !GVL_SmallStation.GetInstance.IsUseLocalRecipe) | |||
//{ | |||
// RecipeFinishInfo.Order_No = RemoteRecipes.ElementAt(index).RecipeCode; | |||
// RecipeFinishInfo.Product_Code = RemoteRecipes.ElementAt(index).RecipeName; | |||
// RecipeFinishInfo.Job_No = (short)trayCode; | |||
// for (int i = 0; i < 20; i++) | |||
// { | |||
// RecipeFinishInfo.Material[i] = new UDT1(); | |||
// } | |||
// for (int i = 0; i < 10; i++) | |||
// { | |||
// RecipeFinishInfo.Powder[i] = new UDT2(); | |||
// } | |||
// for (int i = 0; i < RemoteRecipes.ElementAt(index).RawMaterial.Count; i++) | |||
// { | |||
// RecipeFinishInfo.Material[i].Material_Name = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialName; | |||
// RecipeFinishInfo.Material[i].Material_BarrelNum = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialBarrelNum; | |||
// RecipeFinishInfo.Material[i].Material_Laying_Off_Weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).Laying_Off_Weight * (float)0.001; | |||
// } | |||
// for (int i = 0; i < RemoteRecipes.ElementAt(index).WindSend.Count; i++) | |||
// { | |||
// RecipeFinishInfo.Powder[i].Powder_Weight = RemoteRecipes.ElementAt(index).WindSend.ElementAt(i).DosingCompleWeight; | |||
// } | |||
// RecipeFinishInfo.Ask_For_Finish = true; | |||
// RecipeFinishInfo.DosingTime = Convert.ToInt16(a); | |||
// SiemensDevice.Siemens_PLC_S7.WriteClass<XL_Finish_DB>(RecipeFinishInfo, 2261); | |||
MessageNotify.GetInstance.ShowRunLog($"托盘1,配方{res.RecipeName},配料完成,数据反馈给西门子"); | |||
MessageNotify.GetInstance.ShowRecipeLog(res.RecipeName); | |||
} | |||
else | |||
// MessageNotify.GetInstance.ShowRunLog($"托盘1,配方{res.RecipeName},配料完成,数据反馈给西门子"); | |||
// MessageNotify.GetInstance.ShowRecipeLog(res.RecipeName); | |||
//} | |||
//else | |||
{ | |||
MessageNotify.GetInstance.ShowRunLog($"托盘1,配方{res.RecipeName},配料完成,数据无法反馈给西门子,西门子设备未连接或处于本地配方"); | |||
MessageNotify.GetInstance.ShowRecipeLog(res.RecipeName); | |||
@@ -1285,8 +1316,8 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
{ | |||
ObservableCollection<RemoteRecipeRawMaterial> RawMaterials = new ObservableCollection<RemoteRecipeRawMaterial>(); | |||
ObservableCollection<WindSendRawMaterial> WindSendData = new ObservableCollection<WindSendRawMaterial>(); | |||
if (SiemensDevice.IsConnected) | |||
{ | |||
//if (SiemensDevice.IsConnected) | |||
//{ | |||
if (res != null && res is XL_Start_DB recipe) | |||
{ | |||
if (!string.IsNullOrEmpty(recipe.RecipeCode)) | |||
@@ -1344,7 +1375,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
}); | |||
} | |||
} | |||
} | |||
//} | |||
}), "SiemensRecipeRecive", true); | |||
//将本地配方发送到西门子配方里,执行配料 | |||
@@ -1545,8 +1576,8 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
{ | |||
if (Json<DevicePar>.Data.deviceConnectPar.SiemensConnect) | |||
{ | |||
SiemensDevice.Siemens_PLC_S7.Connect(S7.Net.CpuType.S71500, Siemens_PLC_IP); | |||
if (SiemensDevice.IsConnected) MessageNotify.GetInstance.ShowRunLog("西门子plc连接成功"); | |||
//SiemensDevice.Siemens_PLC_S7.Connect(S7.Net.CpuType.S71500, Siemens_PLC_IP); | |||
//if (SiemensDevice.IsConnected) MessageNotify.GetInstance.ShowRunLog("西门子plc连接成功"); | |||
} | |||
} | |||
catch (Exception ex) | |||
@@ -1555,7 +1586,7 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
} | |||
finally | |||
{ | |||
SiemensDevice.Init(); | |||
// SiemensDevice.Init(); | |||
MessageNotify.GetInstance.ShowRunLog("西门子plc初始化完成"); | |||
} | |||
try | |||
@@ -1590,11 +1621,11 @@ namespace BPASmartClient.JXJFoodSmallStation.Model | |||
} | |||
try | |||
{ | |||
if (!SiemensDevice.IsConnected && Json<DevicePar>.Data.deviceConnectPar.SiemensConnect) | |||
{ | |||
SiemensDevice.Siemens_PLC_S7.Connect(S7.Net.CpuType.S71500, Siemens_PLC_IP); | |||
if (SiemensDevice.IsConnected) MessageNotify.GetInstance.ShowRunLog("西门子PLC重新连接成功"); | |||
} | |||
//if (!SiemensDevice.IsConnected && Json<DevicePar>.Data.deviceConnectPar.SiemensConnect) | |||
//{ | |||
// SiemensDevice.Siemens_PLC_S7.Connect(S7.Net.CpuType.S71500, Siemens_PLC_IP); | |||
// if (SiemensDevice.IsConnected) MessageNotify.GetInstance.ShowRunLog("西门子PLC重新连接成功"); | |||
//} | |||
} | |||
catch (Exception ex) | |||
{ | |||
@@ -9,6 +9,9 @@ namespace BPASmartClient.JXJFoodSmallStation.Model.Siemens | |||
{ | |||
internal class LocalRecipeDataColl | |||
{ | |||
/// <summary> | |||
/// 本地自定义配方集合。 | |||
/// </summary> | |||
public ObservableCollection<RemoteRecipeData> Recipes { get; set; } = new ObservableCollection<RemoteRecipeData>(); | |||
/// <summary> | |||
/// 筛选后的配方显示集合。 | |||
@@ -301,7 +301,7 @@ namespace BPASmartClient.JXJFoodSmallStation.ViewModel | |||
MessageNotify.GetInstance.ShowUserLog($"设置柔性味魔方复位时间:{time}s"); | |||
NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"{time.ToString()}:设置成功!"); | |||
}); | |||
SiemensIsConnect = ProcessControl.GetInstance.SiemensDevice.IsConnected; | |||
//SiemensIsConnect = ProcessControl.GetInstance.SiemensDevice.IsConnected; | |||
HKPlcIsConnect = ProcessControl.GetInstance.HKDevice.IsConnected; | |||
WindSendIsConnect = ProcessControl.GetInstance.WindSendDevice.IsConnected; | |||
} | |||
@@ -45,9 +45,15 @@ namespace BPASmartClient.JXJFoodSmallStation.ViewModel | |||
if (MessageNotify.GetInstance.ShowDialog($"请确认,是否删除订单【{cnt}】?")) | |||
{ | |||
var res = Json<LocalRecipeDataColl>.Data.Recipes.FirstOrDefault(p => p.RecipeCode == cnt); | |||
var res1= Json<LocalRecipeDataColl>.Data.SelectedRecipes.FirstOrDefault(p => p.RecipeCode == cnt); | |||
if (res1 is not null) | |||
{ | |||
Json<LocalRecipeDataColl>.Data.SelectedRecipes.Remove(res1); | |||
} | |||
if (res != null) | |||
{ | |||
Json<LocalRecipeDataColl>.Data.Recipes.Remove(res); | |||
Json<LocalRecipeDataColl>.Save(); | |||
MessageNotify.GetInstance.ShowUserLog($"删除配方——{res.RecipeName}"); | |||
} | |||
} | |||
@@ -18,6 +18,7 @@ namespace BPASmartClient.JXJFoodSmallStation.ViewModel | |||
public SelectRecipesViewModel() | |||
{ | |||
AllRecipes = new(); | |||
SelectRecipes.Clear(); | |||
foreach (var item in Json<LocalRecipeDataColl>.Data.SelectedRecipes) | |||
{ | |||
SelectRecipes.Add(item); | |||