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 { /// /// 把配方PLC点对应数据先写入数据库中 /// public class RecipeToDatabase { #region 基本函数 /// /// 获取本地连接 /// /// private DbHelper getLocalHelper() { return new DatabaseAction().NewDbHelper(Mesnac.Basic.DataSourceFactory.MCDbType.Local); } /// /// 获取网络连接 /// /// private DbHelper getServerHelper() { return new DatabaseAction().NewDbHelper(Mesnac.Basic.DataSourceFactory.MCDbType.Server); } /// /// 判断是否为网络版 /// /// 网络版返回true,单机版返回false private bool IsNet() { bool Result = false; Result = new BaseAction().NetType == BaseAction.NetTypes.Net; return Result; } #endregion #region 下载数据 /// /// 获取网络数据库服务器时间 /// /// 成功返回获取的时间,失败返回本机时间 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 配方主表信息 /// /// 下传配方主表信息至PlcData表 /// /// 成功返回true,失败返回false 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 下传当前配方密炼信息 /// /// 下传当前配方密炼信息至PlcData表 /// /// 下传成功返回true,失败返回false 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 配方密炼辅助方法 /// /// 获取动作代码 /// /// /// 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; } } /// /// 获取当前配方的密炼信息 /// /// public DataTable getCurrentRecipeMixingData() { BasicInfo.RecipeData recipeData = new BasicInfo.RecipeData(); DataTable dt = recipeData.GetCurrentRecipeMixingData(); #region 同时执行 TermCode=11 List rowList = new List(); 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 下载配方称量信息 /// /// 下载配方称量信息 /// /// 称量信息 /// 是否自动下传 /// 下传成功返回1,失败返回其他值 public int DownloadRecipeWeightInfo(DataTable dt, bool isAutoDown) { if (isAutoDown && LastDownloadRecipeWeightInfoPlanID == dt.TableName) { return 0; } LastDownloadRecipeWeightInfoPlanID = dt.TableName; List 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 dicBuff = new Dictionary(); 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 下传当前配方的称量信息 /// /// 下传当前配方的称量信息至PlcData表 /// /// 下传成功返回true,下传失败返回true 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、油1:1、油2:5、粉料:3 要验证是否获取到了罐号 /// /// 称量信息罐号验证:炭黑:0、油1:1、油2:5、粉料:3 要验证是否获取到了罐号 /// /// 成功返回true,失败返回false public bool ValidateJarSerial(List weightInfoList, out List msgList) { bool result = true; string msg = String.Empty; msgList = new List(); 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 /// /// 下传计划车数到Plc /// /// 下传成功返回true,下传失败返回false 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表中的数据 /// /// 清空PLCData表中的数据 /// public void TruncatePlcData() { DbHelper dbHelper = getLocalHelper(); dbHelper.CommandType = CommandType.Text; dbHelper.ClearParameter(); dbHelper.CommandText = "TRUNCATE TABLE PlcData;"; dbHelper.ExecuteNonQuery(); } #endregion #region 下传当前配方信息 /// /// 下传当前配方信息 /// /// 成功返回true,失败返回false 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 业务入口 /// /// 业务入口 /// /// public bool Run(out List msgList) { return ExecRecipeToPlcData(3000 , out msgList); } #region 执行把配方存入PlcData表的主业务方法 /// /// 执行把配方存入PlcData表的主业务方法 /// /// 消息框超时时间,单位:毫秒 /// 成功返回true,失败返回false public bool ExecRecipeToPlcData(int msgTimeout, out List msgList) { lock (String.Empty) { FrmNotify.Instance.Notifys = "开始下传配方信息"; FrmNotify.Instance.Value = 16; msgList = new List(); 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 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 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 } }