using BPA.Communication;
using BPASmartClient.CustomResource.Pages.Model;
using BPASmartClient.FoodStationTest.Model.GVL;
using BPASmartClient.FoodStationTest.Model.HK_PLC;
using BPASmartClient.FoodStationTest.Model.RawMaterial;
using BPA.Helper;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Printing;
using System.Reflection;
using System.Threading;
namespace BPASmartClient.FoodStationTest.Model
{
public class ProcessControl
{
private static volatile ProcessControl _Instance;
public static ProcessControl GetInstance => _Instance ?? (_Instance = new ProcessControl());
private ProcessControl()
{ }
///
/// 配方数据
///
public ObservableCollection RemoteRecipes = new ObservableCollection();
///
/// 原料的名称和料仓的位置对应
///
public Dictionary RawMaterialsNamePos = new Dictionary();
public ObservableCollection RawMaterialsInfo => Json.Data.rawMaterialStockBin;
///
/// 配方队列
///
public ConcurrentQueue RecipeQueueTray1 = new ConcurrentQueue();
///
/// 物料集合
///
public Dictionary> RecipeQueueTray { get; set; } = new Dictionary>();
public HKDeviceStatus HKDevice = new HKDeviceStatus();
public ObservableCollection CommData { get; set; } = new ObservableCollection();
public ObservableCollection ProcessVar { get; set; } = new ObservableCollection();
public DateTime StockBinAlarmTime = DateTime.Now;
public string? HK_PLC_IP => Json.Data.HK_PLC_IP;
public void Init()
{
//初始化物料集合。
for (int i = 0; i < 5; i++)
{
RecipeQueueTray.TryAdd(i, new ConcurrentQueue());
}
PlcVarMonitor();
StockBinNameWithPos();
RawMaterialNameWithCode();
RegisterInit();
DeviceConnect();
//Json.Data.Recipes = TestData.GetInstance.Recipes;//添加测试数据
TaskManage.GetInstance.StartLong(new Action(() =>
{
GVL_SmallStation.GetInstance.DisEnableStockAlarm = Json.Data.deviceConnectPar.ShieldStockbinAlarm;
if (HKDevice.IsConnected)
{
GVL_SmallStation.GetInstance.HeartBeatToPlc = !GVL_SmallStation.GetInstance.HeartBeatToPlc;
HKDevice.HK_PLC_S7.Write("DB4.DBX0.0", GVL_SmallStation.GetInstance.HeartBeatToPlc);
GVL_SmallStation.GetInstance.HeartBeatFromPlc = HKDevice.HK_PLC_S7.Read("DB45.DBX0.0").Content;
if (DeviceInquire.GetInstance.devices.Count < Json.Data.RawMaterialDeviceNum && HKDevice.IsConnected
&& Json.Data.Recipes.Count > 0 && GVL_SmallStation.GetInstance.DisEnableStockBinAlarm == false
&& DateTime.Now.Subtract(StockBinAlarmTime).TotalSeconds >= 60 & !GVL_SmallStation.GetInstance.DisEnableStockAlarm)
{
HKDevice.HK_PLC_S7.Write("DB44.DBX3.0", true);
App.Current.Dispatcher.Invoke(() =>
{
MessageNotify.GetInstance.ShowDialog($"未读取到全部柔性味魔方料仓。", DialogType.Error);
StockBinAlarmTime = DateTime.Now;
});
HKDevice.HK_PLC_S7.Write("DB44.DBX3.0", false);
}
}
Thread.Sleep(200);
}), "海科plc通信心跳", true);
TaskManage.GetInstance.StartLong(new Action(() =>
{
if (GVL_SmallStation.GetInstance.Order_Cancel)
{
CancelOrder();//订单取消,不执行配方流程
}
else
{
ReceviceData();//配方请求
RecipeInfoToHKPLC();//配方配料
}
Thread.Sleep(10);
}), "小料站流程控制", true);
TaskManage.GetInstance.StartLong(new Action(() =>
{
RealTimeData();
Thread.Sleep(10);
}), "西门子PLC和小料站PLC的实时数据交互流程", true);
TaskManage.GetInstance.StartLong(new Action(() =>
{
HKPlcRead();
GetStatus();
Thread.Sleep(10);
}), "海科PLC实时数据", true);
}
///
/// 气缸的传感器值
///
private void GetStatus()
{
for (int i = 0; i < 8; i++)
{
GVL_SmallStation.GetInstance.Cylinder_JackInfo[i] = HKDevice.HK_PLC_S7.Read("DB5.DBX0." + i).Content;
}
for (int i = 0; i < 7; i++)
{
GVL_SmallStation.GetInstance.Cylinder_JackInfo[i + 8] = HKDevice.HK_PLC_S7.Read("DB5.DBX1." + i).Content;
}
GVL_SmallStation.GetInstance.Cylinder_JackInfo[20] = HKDevice.HK_PLC_S7.Read("DB5.DBX3.6").Content;//进料桶气缸
GVL_SmallStation.GetInstance.Cylinder_JackInfo[21] = HKDevice.HK_PLC_S7.Read("DB5.DBX3.7").Content;//出料筒气缸1
GVL_SmallStation.GetInstance.Cylinder_JackInfo[22] = HKDevice.HK_PLC_S7.Read("DB5.DBX4.0").Content;//出料筒气缸2
GVL_SmallStation.GetInstance.Cylinder_JackInfo[23] = HKDevice.HK_PLC_S7.Read("DB5.DBX4.1").Content;//出料筒气缸3
GVL_SmallStation.GetInstance.Cylinder_JackInfo[24] = HKDevice.HK_PLC_S7.Read("DB5.DBX4.2").Content;//托盘1_1气缸
GVL_SmallStation.GetInstance.Cylinder_JackInfo[25] = HKDevice.HK_PLC_S7.Read("DB5.DBX4.3").Content;//托盘1_2气缸
GVL_SmallStation.GetInstance.Cylinder_JackInfo[26] = HKDevice.HK_PLC_S7.Read("DB5.DBX4.4").Content;//托盘2_1气缸
GVL_SmallStation.GetInstance.Cylinder_JackInfo[27] = HKDevice.HK_PLC_S7.Read("DB5.DBX4.5").Content;//托盘2_2气缸
}
///
/// DB块的变量实时值
///
private void HKPlcRead()
{
if (HKDevice.IsConnected)
{
foreach (PropertyInfo item in typeof(PlcReadAddressDB3).GetProperties())
{
int index = Array.FindIndex(CommData.ToArray(), p => p.Name == item.Name);
if (index >= 0)
{
if (item.PropertyType.IsArray)
{
CommData.ElementAt(index).Value = "";
Array array = (Array)item.GetValue(GVL_SmallStation.GetInstance.plcReadDataDB3, null);
foreach (var values in array)
{
string data = values.ToString();
if (data.ToLower() == "false")
data = "0";
if (data.ToLower() == "true")
data = "1";
CommData.ElementAt(index).Value = CommData.ElementAt(index).Value + data + ",";
}
}
else
{
CommData.ElementAt(index).Value = GVL_SmallStation.GetInstance.plcReadDataDB3.GetType().GetProperty(item.Name).GetValue(GVL_SmallStation.GetInstance.plcReadDataDB3, null).ToString();
}
}
}
}
foreach (PropertyInfo item in typeof(GVL_SmallStation).GetProperties())
{
int index = Array.FindIndex(ProcessVar.ToArray(), p => p.Name == item.Name);
if (index >= 0)
{
if (item.PropertyType.IsArray)
{
ProcessVar.ElementAt(index).Value = "";
Array array = (Array)item.GetValue(GVL_SmallStation.GetInstance, null);
foreach (var values in array)
{
string data = values.ToString();
if (data.ToLower() == "false")
data = "0";
if (data.ToLower() == "true")
data = "1";
ProcessVar.ElementAt(index).Value = ProcessVar.ElementAt(index).Value + data + ",";
}
}
else
{
ProcessVar.ElementAt(index).Value = GVL_SmallStation.GetInstance.GetType().GetProperty(item.Name).GetValue(GVL_SmallStation.GetInstance, null).ToString();
}
}
}
}
///
/// 小料站和西门子PLC之间的实时数据
///
private void RealTimeData()
{
if (HKDevice.IsConnected)
{
//获取系统状态
GVL_SmallStation.GetInstance.PlcSystemIsAutoRun = HKDevice.HK_PLC_S7.Read("DB44.DBX0.0").Content;//系统启停
GVL_SmallStation.GetInstance.PlcSystemMode = HKDevice.HK_PLC_S7.Read("DB44.DBX0.1").Content;//系统模式
GVL_SmallStation.GetInstance.PlcSystemIsPause = HKDevice.HK_PLC_S7.Read("DB44.DBX0.2").Content;//系统暂停
GVL_SmallStation.GetInstance.Station1HaveTray = HKDevice.HK_PLC_S7.Read("DB3.DBX40.0").Content;//工站1 有货架
GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[0] = HKDevice.HK_PLC_S7.Read("DB3.DBX2.0").Content;
GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[1] = HKDevice.HK_PLC_S7.Read("DB3.DBX2.1").Content;
GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[2] = HKDevice.HK_PLC_S7.Read("DB3.DBX2.2").Content;
GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[3] = HKDevice.HK_PLC_S7.Read("DB3.DBX2.3").Content;
GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[4] = HKDevice.HK_PLC_S7.Read("DB3.DBX2.4").Content;
if (GVL_SmallStation.GetInstance.WindSendDosingComple)
{
HKDevice.HK_PLC_S7.Write("DB4.DBX4.0", true);
GVL_SmallStation.GetInstance.WindSendDosingComple = false;
MessageNotify.GetInstance.ShowRunLog("风送配料完成信号,发给产线plc信号");
}
if (Json.Data.Recipes.Count <= 3)
{
GVL_SmallStation.GetInstance.IsAllowSiemensSendRecipe = true;
}
GVL_SmallStation.GetInstance.Station1Sensor = HKDevice.HK_PLC_S7.Read("DB3.DBX40.1").Content;
GVL_SmallStation.GetInstance.Station1Cylinder = HKDevice.HK_PLC_S7.Read("DB3.DBX40.2").Content;
GVL_SmallStation.GetInstance.RobotStatus = HKDevice.HK_PLC_S7.Read("DB3.DBB0").Content;
GVL_SmallStation.GetInstance.RobotProgramNum = HKDevice.HK_PLC_S7.Read("DB3.DBB1").Content;
}
}
public void CancelOrder()
{
if (GVL_SmallStation.GetInstance.Order_Cancel) //订单取消
{
if (!string.IsNullOrEmpty(GVL_SmallStation.GetInstance.Order_CancelRecipeCode))
{
string code = GVL_SmallStation.GetInstance.Order_CancelRecipeCode;
int index = Array.FindIndex(Json.Data.Recipes.ToArray(), p => p.RecipeCode == code);
int[] cnt = new int[5] { -1, -1, -1, -1, -1 };
int index1 = -1;
for (int i = 0; i < 5; i++)
{
cnt[i] = Array.FindIndex(RecipeQueueTray[i].ToArray(), p => p == code);
if (cnt[i] >= 0)
{
index1 = i;
}
}
switch (GVL_SmallStation.GetInstance.OrderCancelStep)
{
case 0://前提条件判断
if (index == -1)
{
GVL_SmallStation.GetInstance.OrderCancelStep = 30;
MessageNotify.GetInstance.ShowRunLog($"配方中并未找到订单{code}");
}
else
{
if (index1 >= 0)
{
GVL_SmallStation.GetInstance.OrderCancelStep = 1;
}
else
{
GVL_SmallStation.GetInstance.OrderCancelStep = 20;
}
}
break;
//Case 1-9为
case 1:
if (GVL_SmallStation.GetInstance.RecipeProcessStatus[index] != 0)
{
GVL_SmallStation.GetInstance.RecipeProcessStatus[index] = 0;
HKDevice.HK_PLC_S7.Write("DB4.DBX6." + index1, true);
MessageNotify.GetInstance.ShowRunLog($"PLC正在执行配料流程,正在取消订单:{code}");
GVL_SmallStation.GetInstance.OrderCancelStep = 2;
}
else
{
MessageNotify.GetInstance.ShowRunLog($"AGV未到达工站前,未给plc下发配方,取消订单:{code}");
GVL_SmallStation.GetInstance.OrderCancelStep = 3;
}
break;
case 2:
if (HKDevice.HK_PLC_S7.Read("DB3.DBX42." + index1).Content)
{
if (GVL_SmallStation.GetInstance.Station1Cylinder == false)
{
GVL_SmallStation.GetInstance.OrderCancelStep = 3;
MessageNotify.GetInstance.ShowRunLog($"PLC正在执行配料流程,取消订单:{code}");
}
}
break;
case 3:
// SiemensDevice.Siemens_PLC_S7.Write("DB2201.DBX450.1", true);
GVL_SmallStation.GetInstance.OrderCancelStep = 4;
break;
case 4:
// 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(() =>
{
Json.Data.Recipes.RemoveAt(index);
});
RecipeQueueTray1.TryDequeue(out code);
GVL_SmallStation.GetInstance.RecipeProcessStatus[index] = 0;
GVL_SmallStation.GetInstance.Order_Cancel = false;
GVL_SmallStation.GetInstance.Order_CancelRecipeCode = "";
GVL_SmallStation.GetInstance.OrderCancelStep = 0;
break;
case 20:
GVL_SmallStation.GetInstance.OrderCancelStep = 21;
break;
case 21:
GVL_SmallStation.GetInstance.OrderCancelStep = 29;
MessageNotify.GetInstance.ShowRunLog($"队列1,西门子取消订单完成,订单号:{code}");
break;
case 29:
App.Current.Dispatcher.Invoke(() =>
{
Json.Data.Recipes.RemoveAt(index);
});
GVL_SmallStation.GetInstance.Order_Cancel = false;
GVL_SmallStation.GetInstance.Order_CancelRecipeCode = "";
GVL_SmallStation.GetInstance.SiemensSendRecipeStatus = 0;
GVL_SmallStation.GetInstance.OrderCancelStep = 0;
break;
//30-39为订单还未下发至上位机
case 30:
GVL_SmallStation.GetInstance.OrderCancelStep = 31;
break;
case 31:
GVL_SmallStation.GetInstance.OrderCancelStep = 39;
MessageNotify.GetInstance.ShowRunLog($"西门子取消订单完成,订单号:{code}");
break;
case 39:
GVL_SmallStation.GetInstance.Order_Cancel = false;
GVL_SmallStation.GetInstance.Order_CancelRecipeCode = "";
GVL_SmallStation.GetInstance.OrderCancelStep = 0;
break;
}
}
}
}
///
/// 将配方添加到配方队列中
///
private void ReceviceData()
{
RemoteRecipes = Json.Data.Recipes;
if (RemoteRecipes.Count > 0)
{
foreach (var data in RemoteRecipes)
{
if (data.TrayCode == 1)
{
for (int i = 0; i < 5; i++)
{
if (GVL_SmallStation.GetInstance.NotUseSmallStation)
{
//查询都不包含此配方
if (RecipeQueueTray[i].Count == 0 && !RecipeQueueTray[0].Contains(data.RecipeCode) && !RecipeQueueTray[1].Contains(data.RecipeCode) && !RecipeQueueTray[2].Contains(data.RecipeCode) && !RecipeQueueTray[3].Contains(data.RecipeCode) && !RecipeQueueTray[4].Contains(data.RecipeCode))
{
RecipeQueueTray[i].Enqueue(data.RecipeCode);
MessageNotify.GetInstance.ShowRunLog($"本地配方配料 ,不使用小料配料,配方{data.RecipeCode},加入配方{i}");
}
}
else if (GVL_SmallStation.GetInstance.PlcAllowIssueRecipe[i])
{
if (RecipeQueueTray[i].Count == 0 && !RecipeQueueTray[0].Contains(data.RecipeCode) && !RecipeQueueTray[1].Contains(data.RecipeCode) && !RecipeQueueTray[2].Contains(data.RecipeCode) && !RecipeQueueTray[3].Contains(data.RecipeCode) && !RecipeQueueTray[4].Contains(data.RecipeCode))
{
RecipeQueueTray[i].Enqueue(data.RecipeCode);
MessageNotify.GetInstance.ShowRunLog($"本地配方配料 ,等待plc允许配料,配方{data.RecipeCode},加入配方{i}");
}
}
}
}
}
}
else
{
for (int i = 0; i < 5; i++)
{
RecipeQueueTray[i].Clear();
GVL_SmallStation.GetInstance.RecipeProcessStatus[i] = 0;
}
GVL_SmallStation.GetInstance.WindSendDosingStatus = 0;
GVL_SmallStation.GetInstance.WindSendDosing = false;
}
}
///
/// 小料站配料
///
private void RecipeInfoToHKPLC()
{
if (!GVL_SmallStation.GetInstance.NotUseSmallStation)
{
//如果使用小料站配料,更新查询5个工位的AGV状态。
for (int i = 0; i < 5; i++)
{
switch (GVL_SmallStation.GetInstance.Tray_AGVLogic[i])
{
case 0:
if (GVL_SmallStation.GetInstance.AGV_PutTray1Finish && (RecipeQueueTray[i].Count > 0) && GVL_SmallStation.GetInstance.AGVIsGetTray == false)
{
GVL_SmallStation.GetInstance.AGVIsGetTray = true;
HKDevice.HK_PLC_S7.Write("DB4.DBX8." + i, true);
GVL_SmallStation.GetInstance.AGV_PutTray1Finish = false;
GVL_SmallStation.GetInstance.Tray_AGVLogic[i] = 1;
MessageNotify.GetInstance.ShowRunLog("AGV到位 发送到位信号给plc");
}
break;
case 1:
if (GVL_SmallStation.GetInstance.Station1HaveTray)
{
HKDevice.HK_PLC_S7.Write("DB4.DBX8." + i, false);
GVL_SmallStation.GetInstance.Tray_AGVLogic[i] = 2;
MessageNotify.GetInstance.ShowRunLog("托盘1有货架");
}
break;
case 2:
if (GVL_SmallStation.GetInstance.AGV_GetTray1Finish && GVL_SmallStation.GetInstance.RecipeProcessStatus[i] == 0)
{
GVL_SmallStation.GetInstance.AGVIsGetTray = false;
HKDevice.HK_PLC_S7.Write("DB4.DBX10." + i, true);
GVL_SmallStation.GetInstance.Tray_AGVLogic[i] = 3;
MessageNotify.GetInstance.ShowRunLog("AGV取托盘1完成,发送给海科信号后1s后复位");
}
break;
case 3:
if (HKDevice.HK_PLC_S7.Read("DB4.DBX10." + i).Content)
{
Thread.Sleep(1000);
HKDevice.HK_PLC_S7.Write("DB4.DBX10." + i, false);
GVL_SmallStation.GetInstance.Tray_AGVLogic[i] = 0;
GVL_SmallStation.GetInstance.AGV_GetTray1Finish = false;
MessageNotify.GetInstance.ShowRunLog("AGV取托盘1完成,信号复位");
}
break;
default:
break;
}
}
}
foreach (var recipe in RecipeQueueTray)
{
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)
{
string code = RemoteRecipes.ElementAt(index).RecipeCode;
int trayCode = RemoteRecipes.ElementAt(index).TrayCode;
string recipeName = RemoteRecipes.ElementAt(index).RecipeName;
string windSend = RemoteRecipes.ElementAt(index).ToString();
if (trayCode == 1)
{
if (GVL_SmallStation.GetInstance.NotUseSmallStation)
{
if (GVL_SmallStation.GetInstance.AGV_PutTray1Finish)
{
Thread.Sleep(5000);
var res = Json.Data.Recipes.FirstOrDefault(p => p.RecipeCode == code);
if (/*SiemensDevice.IsConnected &&*/ !GVL_SmallStation.GetInstance.IsUseLocalRecipe)
{
MessageNotify.GetInstance.ShowRunLog($"托盘1,配方{res.RecipeName},配料完成,数据反馈给西门子");
}
else
{
MessageNotify.GetInstance.ShowRunLog($"托盘1,配方{res.RecipeName},配料完成,数据无法反馈给西门子,西门子设备未连接或处于本地配方");
}
GVL_SmallStation.GetInstance.WindSendDosing = false;
App.Current.Dispatcher.Invoke(() =>
{
Json.Data.Recipes.Remove(res);
});
RecipeQueueTray[recipeNum].TryDequeue(out code);
GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] = 0;
GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 0;
}
}
else
{
//粉料仓下发配方并配料。
if (/*GVL_SmallStation.GetInstance.IsUseWindSend &&*/ GVL_SmallStation.GetInstance.WindSendDosing == false /*&& GVL_SmallStation.GetInstance.Tray_AGVLogic[recipeNum] == 2*/)
{
}
else
{
if (Delay.GetInstance("delayTime").Start(true, 60))
{
Delay.GetInstance("delayTime").Start(false, 60);
MessageNotify.GetInstance.ShowRunLog($"风送设备PLC未连接");
}
}
}
//上位机下发配方。并检测下发完成。
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("DB3.DBX4." + recipeNum).Content;
if (recipeReceviceFinish && GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] == 1)
{
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 <= Json.Data.RawMaterialDeviceNum; i++)
{
int indexArr = -1;
//获取配方每个配方的三个桶的位置。
if (GVL_SmallStation.GetInstance.plcReadDataDB3.StockBinAllowIssue[i - 1])
{
switch (recipeNum)
{
case 0:
indexArr = Array.FindIndex(GVL_SmallStation.GetInstance.plcReadDataDB3.Recipe1BarrelPosReserve.ToArray(), p => p == i);
break;
case 1:
indexArr = Array.FindIndex(GVL_SmallStation.GetInstance.plcReadDataDB3.Recipe2BarrelPosReserve.ToArray(), p => p == i);
break;
case 2:
indexArr = Array.FindIndex(GVL_SmallStation.GetInstance.plcReadDataDB3.Recipe3BarrelPosReserve.ToArray(), p => p == i);
break;
case 3:
indexArr = Array.FindIndex(GVL_SmallStation.GetInstance.plcReadDataDB3.Recipe4BarrelPosReserve.ToArray(), p => p == i);
break;
case 4:
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)
{
string commInfo = HKDevice.HK_PLC_S7.Write("DB4.DBX12." + (i - 1), true).IsSuccess.ToString();
MessageNotify.GetInstance.ShowRunLog(commInfo);
}
else if (i >= 9 && i <= 15)
{
string commInfo1 = HKDevice.HK_PLC_S7.Write("DB4.DBX13." + (i - 9), true).IsSuccess.ToString();
MessageNotify.GetInstance.ShowRunLog(commInfo1);
}
GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] = GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum].SetBitValue((byte)i, false);//配料完成设备写成false
GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] = GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum].SetBitValue((byte)i, true);//配料完成设备写成false
}
//写入重量并开始配料
else
{
if (loc_index >= 0)
{
DeviceInquire.GetInstance.GetDevice((int)i)?.Start(weight);//根据料仓编号 启动并写入每个原料重量
GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] = GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum].SetBitValue((byte)i, true);//配料完成设备写成false
}
else
{
MessageNotify.GetInstance.ShowRunLog($"托盘1,配方编号:{code},配方号{recipeNum + 1},{indexArr + 1}号桶,错误没有找到{(int)i}号仓的配方");
}
}
MessageNotify.GetInstance.ShowRunLog($"托盘1,配方编号:{code},配方号{recipeNum + 1},{indexArr + 1}号桶,{(int)i}号仓,正在配料");
}
else
{
//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);
if (res < 0)
{
}
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.Data.deviceParModels.ToArray(), p => p.MaterialName == DeviceInquire.GetInstance.GetDevice(i).DeviceName);
if (iIndex >= 0)
{
//如果偏差过大则报警。
if (Math.Abs(Json.Data.deviceParModels.ElementAt(iIndex).ErrorRange) < AlarmRange)
{
HKDevice.HK_PLC_S7.Write("DB44.DBX3.0", true);
App.Current.Dispatcher.Invoke(() =>
{
MessageNotify.GetInstance.ShowDialog($"{i}号仓配料误差过大,设置出料重量{RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).RawMaterialWeight * 1000}g,实际出料重量{RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(res).Laying_Off_Weight}g,相差{AlarmRange}g,允许误差为{Math.Abs(Json.Data.deviceParModels.ElementAt(iIndex).ErrorRange)}g,请联系人工处理", DialogType.Warning);
HKDevice.HK_PLC_S7.Write("DB44.DBX3.0", false);
});
}
}
//对海科PLC写入味魔方配料完成。
if (i >= 1 && i <= 8)
{
string commInfo = HKDevice.HK_PLC_S7.Write("DB4.DBX12." + (i - 1), true).IsSuccess.ToString();
MessageNotify.GetInstance.ShowRunLog(commInfo);
}
else if (i >= 9 && i <= 15)
{
string commInfo1 = HKDevice.HK_PLC_S7.Write("DB4.DBX13." + (i - 9), true).IsSuccess.ToString();
MessageNotify.GetInstance.ShowRunLog(commInfo1);
}
GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] = GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum].SetBitValue((byte)i, false);//配料完成设备写成false
MessageNotify.GetInstance.ShowRunLog($"配方{recipeNum},{GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum].ToBinString()}");
}
}
}
}
//配方整体配料完成处理。
bool DosingComple = HKDevice.HK_PLC_S7.Read("DB3.DBX6." + recipeNum).Content;
if ((RTrig.GetInstance("配方配料完成").Start(DosingComple)) || (GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] > 0 && DosingComple))
{
//配方制作完成数量+1
GVL_SmallStation.GetInstance.RecipeDosingCompleNum = GVL_SmallStation.GetInstance.RecipeDosingCompleNum + 1;
GVL_SmallStation.GetInstance.StockBinDosingIssue[recipeNum] = 0;
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}号仓");
}
}
}
var res = Json.Data.Recipes.FirstOrDefault(p => p.RecipeCode == code);
double a = DateTime.Now.Subtract(GVL_SmallStation.GetInstance.DosingTime[recipeNum]).TotalSeconds;
foreach (var item in RemoteRecipes.ElementAt(index).RawMaterial)
{
MessageNotify.GetInstance.ShowRunLog($"{item.RawMaterialName},下料重量:{item.Laying_Off_Weight}g");
}
GVL_SmallStation.GetInstance.WindSendDosing = false;
//移除配方。
App.Current.Dispatcher.Invoke(() =>
{
Json.Data.Recipes.Remove(res);
});
RecipeQueueTray[recipeNum].TryDequeue(out code);
GVL_SmallStation.GetInstance.RecipeStockBinDosing[recipeNum] = 0;
GVL_SmallStation.GetInstance.RecipeProcessStatus[recipeNum] = 0;
}
}
}
}
}
}
}
///
/// 复位所有料仓。
///
private void StockBinInit()
{
for (int i = 1; i <= Json.Data.RawMaterialDeviceNum; i++)
{
if (DeviceInquire.GetInstance.GetDevice(i).deviceStatus.RunStatus == 3)
{
DeviceInquire.GetInstance.GetDevice(i).StatusReset();
}
}
}
///
/// 料仓的位置和原料名称的对应
///
public void StockBinNameWithPos()
{
RawMaterialsNamePos.Clear();
foreach (var material in RawMaterialsInfo)
{
if (!string.IsNullOrEmpty(material.RawMaterialName))
{
if (!RawMaterialsNamePos.ContainsKey(material.RawMaterialName))
{
RawMaterialsNamePos.Add(material.RawMaterialName, (short)material.RawMaterialLocation);
}
}
}
}
///
/// PLC的DB3变量列表。初始化PLC读取DB块变量以及流程变量数据。
///
public void PlcVarMonitor()
{
foreach (PropertyInfo item in typeof(PlcReadAddressDB3).GetProperties())
{
if (Attribute.IsDefined(item, typeof(VarCommAttribute)))
{
string type = item.PropertyType.ToString();
CommData.Add(new PlcInfos()
{
Count = CommData.Count + 1,
Name = item.Name,
Address = item.GetCustomAttribute().Address,
Type = type.Substring(type.IndexOf(".") + 1),
Describe = item.GetCustomAttribute().Describe,
Value = item.GetValue(GVL_SmallStation.GetInstance.plcReadDataDB3).ToString(),
});
}
}
foreach (PropertyInfo item in typeof(GVL_SmallStation).GetProperties())
{
if (Attribute.IsDefined(item, typeof(VarCommAttribute)))
{
string type = item.PropertyType.ToString();
ProcessVar.Add(new PlcInfos()
{
Count = ProcessVar.Count + 1,
Name = item.Name,
Type = type.Substring(type.IndexOf(".") + 1),
Address = item.GetCustomAttribute().Address,
Describe = item.GetCustomAttribute().Describe,
Value = item.GetValue(GVL_SmallStation.GetInstance).ToString()
});
}
}
}
///
/// 注册需要用到的委托,主要是用于手动控制的。
///
public void RegisterInit()
{
//手动控制气缸 DB5.DBX0.0~DB5.DBX4.5
ActionManage.GetInstance.Register(new Action