You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

707 lines
26 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using Mesnac.Codd.Session;
using Mesnac.Action.Base;
using Mesnac.Action.Feeding.Sys;
using Mesnac.Action.Feeding.FeedingPlc;
namespace Mesnac.Action.Feeding.BasicInfo
{
/// <summary>
/// 把配方PLC点对应数据先写入数据库中
/// </summary>
public class RecipeToDatabase
{
#region 基本函数
/// <summary>
/// 获取本地连接
/// </summary>
/// <returns></returns>
private DbHelper getLocalHelper()
{
return new DatabaseAction().NewDbHelper(Mesnac.Basic.DataSourceFactory.MCDbType.Local);
}
/// <summary>
/// 获取网络连接
/// </summary>
/// <returns></returns>
private DbHelper getServerHelper()
{
return new DatabaseAction().NewDbHelper(Mesnac.Basic.DataSourceFactory.MCDbType.Server);
}
/// <summary>
/// 判断是否为网络版
/// </summary>
/// <returns>网络版返回true,单机版返回false</returns>
private bool IsNet()
{
bool Result = false;
Result = new BaseAction().NetType == BaseAction.NetTypes.Net;
return Result;
}
#endregion
#region 下载数据
/// <summary>
/// 获取网络数据库服务器时间
/// </summary>
/// <returns>成功返回获取的时间,失败返回本机时间</returns>
private DateTime Now()
{
if (IsNet())
{
try
{
DbHelper dbHelper = getServerHelper();
dbHelper.CommandType = CommandType.Text;
dbHelper.ClearParameter();
dbHelper.CommandText = "select getdate();";
DateTime time = (DateTime)dbHelper.ToScalar();
new Basic.LocalTime().Set(time);
return time;
}
catch
{
return DateTime.Now;
}
}
else
{
return DateTime.Now;
}
}
private PlcData.DataInfo[] getValue(DataRow row, PlcRecipeWriteItem item)
{
PlcData.DataInfo[] buff = new PlcData.DataInfo[item.ValueLen];
for (int i = 0; i < buff.Length; i++)
{
PlcData.DataInfo datainfo = new PlcData.DataInfo();
datainfo.PlcDataValue = 0;
datainfo.EquipRunName = item.EquipRunName;
datainfo.PlcSchemaField = item.DataFieldName;
buff[i] = datainfo;
}
if (row == null)
{
return buff;
}
if (row.Table.Columns.Contains(item.DataFieldName))
{
item.SetValue = row[item.DataFieldName];
}
else
{
item.SetValue = item.DefaultValue;
}
if (item.DataType.Equals("now", StringComparison.CurrentCultureIgnoreCase))
{
item.SetValue = Now();
}
int[] data = item.WriteData();
int len = data.Length;
if (len > buff.Length)
{
len = buff.Length;
}
for (int i = 0; i < len; i++)
{
PlcData.DataInfo datainfo = new PlcData.DataInfo();
datainfo.PlcDataValue = data[i];
datainfo.EquipRunName = item.EquipRunName;
datainfo.PlcSchemaField = item.DataFieldName;
buff[i] = datainfo;
}
return buff;
}
#region 配方主表信息
/// <summary>
/// 下传配方主表信息至PlcData表
/// </summary>
/// <returns>成功返回true失败返回false</returns>
public bool DownloadCurrentRecipeMainInfo()
{
BasicInfo.RecipeData recipeData = new BasicInfo.RecipeData();
DataTable dt = recipeData.GetCurrentRecipeData();
if (dt.Rows.Count == 0)
{
return false;
}
PlcRecipeWriter writer = PlcSchemaHandler.Instance.GetPlcRecipeWriter("PmtRecipe").FirstOrDefault();
foreach (PlcRecipeWriteItem item in writer.SchemaList)
{
//object[] buff = getValue(dt.Rows[0], item);
//if (!PlcData.Instance.DataWrite(item.DataFieldName,
// item.EquipRunName,
// item.PlcShifting, buff))
//{
// return false;
//}
PlcData.DataInfo[] buff = getValue(dt.Rows[0], item);
object[] values = new object[buff.Length];
for (int i = 0; i < buff.Length; i++)
{
values[i] = buff[i].PlcDataValue;
}
if (!PlcData.Instance.PlcWriteByRunName(item.EquipRunName,
item.PlcShifting, values))
{
return false;
}
}
return true;
}
#endregion
#region 下传当前配方密炼信息
/// <summary>
/// 下传当前配方密炼信息至PlcData表
/// </summary>
/// <returns>下传成功返回true失败返回false</returns>
public bool DownloadCurrentRecipeMixingInfo()
{
DataTable dt_mixing = getCurrentRecipeMixingData();
if (dt_mixing.Rows.Count == 0)
{
return false;
}
PlcRecipeWriter writer = PlcSchemaHandler.Instance.GetPlcRecipeWriter("PmtRecipeMixing").FirstOrDefault();
int maxLen = 0;
foreach (PlcRecipeWriteItem item in writer.SchemaList)
{
maxLen += item.ValueLen * writer.ThisCount;
}
PlcData.DataInfo[] all = new PlcData.DataInfo[maxLen];
int shifting = 0;
for (int i = 0; i < writer.ThisCount; i++)
{
foreach (PlcRecipeWriteItem item in writer.SchemaList)
{
PlcData.DataInfo[] dataNull = getValue(null, item);
foreach (PlcData.DataInfo d in dataNull)
{
all[shifting] = d;
shifting++;
}
}
}
shifting = 0;
foreach (DataRow row in dt_mixing.Rows)
{
foreach (PlcRecipeWriteItem item in writer.SchemaList)
{
PlcData.DataInfo[] buff = getValue(row, item);
for (int i = 0; i < buff.Length; i++)
{
all[i + shifting] = buff[i];
}
shifting += buff.Length;
}
}
//if (!PlcData.Instance.DataWrite(writer.EquipRunName, all))
//{
// return false;
//}
object[] values = new object[all.Length];
for (int i = 0; i < all.Length; i++)
{
values[i] = all[i].PlcDataValue;
}
if (!PlcData.Instance.PlcWriteByRunName(writer.EquipRunName, values))
{
return false;
}
return true;
}
#endregion
#region 配方密炼辅助方法
/// <summary>
/// 获取动作代码
/// </summary>
/// <param name="row"></param>
/// <returns></returns>
private int getActionCode(DataRow row)
{
string fieldName = "ActionAddress";
int icode = 0;
if (row[fieldName] != null && row[fieldName] != DBNull.Value
&& int.TryParse(row[fieldName].ToString(), out icode))
{
return icode;
}
else
{
return 0;
}
}
/// <summary>
/// 获取当前配方的密炼信息
/// </summary>
/// <returns></returns>
public DataTable getCurrentRecipeMixingData()
{
BasicInfo.RecipeData recipeData = new BasicInfo.RecipeData();
DataTable dt = recipeData.GetCurrentRecipeMixingData();
#region 同时执行 TermCode=11
List<DataRow> rowList = new List<DataRow>();
foreach (DataRow row in dt.Rows)
{
string fieldName = "TermCode";
if (row[fieldName] != null && row[fieldName] != DBNull.Value
&& row[fieldName].ToString().Trim() == "11")
{
DataRow lastRow = rowList[rowList.Count - 1];
int icode = getActionCode(row) + getActionCode(lastRow);
lastRow["ActionAddress"] = icode;
continue;
}
rowList.Add(row);
}
#endregion
DataTable dt_mixing = dt.Clone();
for (int i = 0; i < rowList.Count; i++)
{
DataRow row = dt_mixing.NewRow();
foreach (DataColumn dc in dt.Columns)
{
row[dc.ColumnName] = rowList[i][dc.ColumnName];
}
dt_mixing.Rows.Add(row);
}
return dt_mixing;
}
#endregion
#region 配方称量
//上一次下传的称量信息的计划编号
public static string LastDownloadRecipeWeightInfoPlanID = string.Empty;
#region 下载配方称量信息
/// <summary>
/// 下载配方称量信息
/// </summary>
/// <param name="dt">称量信息</param>
/// <param name="isAutoDown">是否自动下传</param>
/// <returns>下传成功返回1失败返回其他值</returns>
public int DownloadRecipeWeightInfo(DataTable dt, bool isAutoDown)
{
if (isAutoDown && LastDownloadRecipeWeightInfoPlanID == dt.TableName)
{
return 0;
}
LastDownloadRecipeWeightInfoPlanID = dt.TableName;
List<PlcRecipeWriter> writerLst = PlcSchemaHandler.Instance.GetPlcRecipeWriter("PmtRecipeWeight");
foreach (PlcRecipeWriter writer in writerLst)
{
int maxLen = 0;
foreach (PlcRecipeWriteItem item in writer.SchemaList)
{
maxLen += item.ValueLen * writer.ThisCount;
}
PlcData.DataInfo[] all = new PlcData.DataInfo[maxLen];
int shifting = 0;
for (int i = 0; i < writer.ThisCount; i++)
{
foreach (PlcRecipeWriteItem item in writer.SchemaList)
{
PlcData.DataInfo[] dataNull = getValue(null, item);
foreach (PlcData.DataInfo d in dataNull)
{
all[shifting] = d;
shifting++;
}
}
}
shifting = 0;
if (writer.ThisType != 4) //非小料称量正常
{
foreach (DataRow row in dt.Rows)
{
if (!row["WeightType"].ToString().Equals(writer.ThisType.ToString(), StringComparison.CurrentCultureIgnoreCase))
{
continue;
}
foreach (PlcRecipeWriteItem item in writer.SchemaList)
{
PlcData.DataInfo[] buff = getValue(row, item);
for (int i = 0; i < buff.Length; i++)
{
all[i + shifting] = buff[i];
}
shifting += buff.Length;
}
}
//if (!PlcData.Instance.DataWrite(writer.EquipRunName, all))
//{
// return -1;
//}
//if (!PlcData.Instance.PlcWriteByRunName(writer.EquipRunName, all))
//{
// return -1;
//}
}
else
{
//小料称量单独处理,需要把多个小料称量设定值合并为一条、误差合并为一条
Dictionary<string, PlcData.DataInfo[]> dicBuff = new Dictionary<string, PlcData.DataInfo[]>();
foreach (DataRow row in dt.Rows)
{
if (!row["WeightType"].ToString().Equals(writer.ThisType.ToString(), StringComparison.CurrentCultureIgnoreCase))
{
continue;
}
foreach (PlcRecipeWriteItem item in writer.SchemaList)
{
PlcData.DataInfo[] buff = getValue(row, item);
if (!dicBuff.ContainsKey(item.DataFieldName))
{
dicBuff.Add(item.DataFieldName, buff);
}
else
{
for (int i = 0; i < buff.Length; i++)
{
dicBuff[item.DataFieldName][i].PlcDataValue = Convert.ToInt32(dicBuff[item.DataFieldName][i].PlcDataValue) + Convert.ToInt32(buff[i].PlcDataValue);
}
}
}
}
foreach(string key in dicBuff.Keys)
{
for (int i = 0; i < dicBuff[key].Length; i++)
{
all[i + shifting] = dicBuff[key][i];
}
shifting += dicBuff[key].Length;
}
//if (!PlcData.Instance.DataWrite(writer.EquipRunName, all))
//{
// return -1;
//}
//if (!PlcData.Instance.PlcWriteByRunName(writer.EquipRunName, all))
//{
// return -1;
//}
}
object[] values = new object[all.Length];
for (int i = 0; i < all.Length; i++)
{
values[i] = all[i].PlcDataValue;
}
if (!PlcData.Instance.PlcWriteByRunName(writer.EquipRunName, values))
{
return -1;
}
}
return 1;
}
#endregion
#region 下传当前配方的称量信息
/// <summary>
/// 下传当前配方的称量信息至PlcData表
/// </summary>
/// <returns>下传成功返回true下传失败返回true</returns>
public bool DownloadCurrentRecipeWeightInfo()
{
BasicInfo.RecipeData recipeData = new BasicInfo.RecipeData();
DataTable dt = recipeData.GetCurrentRecipeWeigthData();
if (dt.Rows.Count == 0)
{
ICSharpCode.Core.LoggingService.Warn("配方错误:没有称量信息!");
return false;
}
return DownloadRecipeWeightInfo(dt, false) >= 0;
}
#endregion
#region 称量信息罐号验证炭黑0、油11、油25、粉料3 要验证是否获取到了罐号
/// <summary>
/// 称量信息罐号验证炭黑0、油11、油25、粉料3 要验证是否获取到了罐号
/// </summary>
/// <returns>成功返回true失败返回false</returns>
public bool ValidateJarSerial(List<RecipeData.RecipeWeightInfo> weightInfoList, out List<string> msgList)
{
bool result = true;
string msg = String.Empty;
msgList = new List<string>();
if (weightInfoList == null || weightInfoList.Count == 0)
{
msg = "配方错误:没有称量信息!";
ICSharpCode.Core.LoggingService.Warn(msg);
msgList.Add(msg);
return false;
}
foreach (RecipeData.RecipeWeightInfo weightInfo in weightInfoList)
{
if (weightInfo.ActCode == 1)
{
if (weightInfo.WeightType == 0 || weightInfo.WeightType == 1 || weightInfo.WeightType == 5 || weightInfo.WeightType == 3)
{
if (weightInfo.JarNum <= 0)
{
msg = "罐号获取失败:称量类型 = " + Global.GetJarTypeByWeightType(weightInfo.WeightType.ToString());
ICSharpCode.Core.LoggingService.Warn(msg);
msgList.Add(msg);
return false;
}
}
}
}
return result;
}
#endregion
#endregion
#region 下传计划车数到Plc
/// <summary>
/// 下传计划车数到Plc
/// </summary>
/// <returns>下传成功返回true下传失败返回false</returns>
private bool DownLoadSetNumber()
{
PlanLog log = PlanCommon.PlanLog;
if (log == null)
{
ICSharpCode.Core.LoggingService.Warn("下传计划车数失败:没有计划日志!");
return false;
}
int nNumber = PlanCommon.GetPlanNum(Basic.DataSourceFactory.MCDbType.Local, log.LastPlanID);
if (nNumber == -1)
{
ICSharpCode.Core.LoggingService.Warn("下传计划车数失败:获取计划数失败!");
return false;
}
//bool result = PlcData.Instance.DataWrite(PlcData.Instance.RecipeSetNumber, new object[] { nNumber });
bool result = PlcData.Instance.PlcWriteByDataKey(PlcData.Instance.RecipeSetNumber, new object[] { nNumber });
if (result)
{
//result = PlcData.Instance.DataWrite(PlcData.Instance.WeightSetNumber, new object[] { nNumber });
result = PlcData.Instance.PlcWriteByDataKey(PlcData.Instance.WeightSetNumber, new object[] { nNumber });
}
return result;
}
#endregion
#region 清空PLCData表中的数据
/// <summary>
/// 清空PLCData表中的数据
/// </summary>
public void TruncatePlcData()
{
DbHelper dbHelper = getLocalHelper();
dbHelper.CommandType = CommandType.Text;
dbHelper.ClearParameter();
dbHelper.CommandText = "TRUNCATE TABLE PlcData;";
dbHelper.ExecuteNonQuery();
}
#endregion
#region 下传当前配方信息
/// <summary>
/// 下传当前配方信息
/// </summary>
/// <returns>成功返回true失败返回false</returns>
public bool DownloadCurrentRecipeInfo()
{
try
{
//TruncatePlcData();
bool Result = false;
//下传配方主信息
FrmNotify.Instance.Notifys = "下传配方主信息";
FrmNotify.Instance.Value = 35;
Result = DownloadCurrentRecipeMainInfo();
if (!Result)
{
return false;
}
//下传配方密炼信息
FrmNotify.Instance.Notifys = "下传配方密炼信息";
FrmNotify.Instance.Value = 50;
Result = DownloadCurrentRecipeMixingInfo();
if (!Result)
{
return false;
}
//下传配方称量信息
FrmNotify.Instance.Notifys = "下传配方称量信息";
FrmNotify.Instance.Value = 75;
Result = DownloadCurrentRecipeWeightInfo();
if (!Result)
{
return false;
}
//下传生产车次
FrmNotify.Instance.Notifys = "下传生产车次";
FrmNotify.Instance.Value = 90;
Result = DownLoadSetNumber();
if (!Result)
{
return false;
}
return true;
}
catch (Exception ex)
{
FrmNotify.Instance.Destory(); //销毁对话框
ICSharpCode.Core.LoggingService.Error("下传配方失败:" + ex.Message);
ICSharpCode.Core.LoggingService.Error(ex.StackTrace);
return false;
}
finally
{
FrmNotify.Instance.Notifys = "配方下传完毕!";
FrmNotify.Instance.Value = 100;
FrmNotify.Instance.Destory(); //销毁对话框
}
}
#endregion
#endregion
#region 业务入口
/// <summary>
/// 业务入口
/// </summary>
/// <returns></returns>
public bool Run(out List<string> msgList)
{
return ExecRecipeToPlcData(3000 , out msgList);
}
#region 执行把配方存入PlcData表的主业务方法
/// <summary>
/// 执行把配方存入PlcData表的主业务方法
/// </summary>
/// <param name="msgTimeout">消息框超时时间,单位:毫秒</param>
/// <returns>成功返回true失败返回false</returns>
public bool ExecRecipeToPlcData(int msgTimeout, out List<string> msgList)
{
lock (String.Empty)
{
FrmNotify.Instance.Notifys = "开始下传配方信息";
FrmNotify.Instance.Value = 16;
msgList = new List<string>();
StringBuilder sbMsg = new StringBuilder();
BasicInfo.RecipeData recipeData = new BasicInfo.RecipeData();
if (PlcData.Instance.MixerAuto.LastValue.ToInt() == 0)
{
sbMsg.AppendLine("密炼机本控");
msgList.Add("密炼机本控");
}
if (PlcData.Instance.MixerNormal.LastValue.ToInt() == 0)
{
sbMsg.AppendLine("密炼机故障");
msgList.Add("密炼机故障");
}
#region RecipeWeightInfo
List<BasicInfo.RecipeData.RecipeWeightInfo> weightlst = recipeData.GetCurrentRecipeWeightInfo();
bool isExists = false;
foreach (BasicInfo.RecipeData.RecipeWeightInfo weight in weightlst)
{
if (weight.WeightType == 0)
{
isExists = true;
break;
}
}
if (isExists)
{
if (PlcData.Instance.CarbonNormal.LastValue.ToInt() == 0)
{
sbMsg.AppendLine("炭黑秤故障");
msgList.Add("炭黑秤故障");
}
if (PlcData.Instance.CarbonAuto.LastValue.ToInt() == 0)
{
sbMsg.AppendLine("炭黑秤手动");
msgList.Add("炭黑秤手动");
}
}
isExists = false;
foreach (BasicInfo.RecipeData.RecipeWeightInfo weight in weightlst)
{
if (weight.WeightType == 1)
{
isExists = true;
break;
}
}
if (isExists)
{
if (PlcData.Instance.OilNormal.LastValue.ToInt() == 0)
{
sbMsg.AppendLine("油秤故障");
msgList.Add("油秤故障");
}
if (PlcData.Instance.OilAuto.LastValue.ToInt() == 0)
{
sbMsg.AppendLine("油秤手动");
msgList.Add("油秤手动");
}
}
isExists = false;
foreach (BasicInfo.RecipeData.RecipeWeightInfo weight in weightlst)
{
if (weight.WeightType == 3)
{
isExists = true;
break;
}
}
if (isExists)
{
if (PlcData.Instance.FenLiaoNormal.LastValue.ToInt() == 0)
{
sbMsg.AppendLine("粉料秤故障");
msgList.Add("粉料秤故障");
}
if (PlcData.Instance.FenLiaoAuto.LastValue.ToInt() == 0)
{
sbMsg.AppendLine("粉料秤手动");
msgList.Add("粉料秤手动");
}
}
#endregion
ICSharpCode.Core.LoggingService.Info(sbMsg.ToString());
List<string> validateJarSerialMsgList = null;
bool Result = this.ValidateJarSerial(weightlst, out validateJarSerialMsgList);
msgList.AddRange(validateJarSerialMsgList);
if (Result)
{
FrmNotify.Instance.Notifys = "正在下传当前配方信息";
FrmNotify.Instance.Value = 25;
Result = DownloadCurrentRecipeInfo();
}
//Mesnac.Equips.Factory.Instance.Read();
new FeedingAction().RefreshCustomEquip(); //刷新自定义设备变量
return Result;
}
}
#endregion
#endregion
}
}