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.

1133 lines
53 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 MaterialTraceability.Common;
using MaterialTraceability.Entity.DAO;
using MaterialTraceability.Entity.DTO;
using MaterialTraceability.Entity.Enum;
using MaterialTraceability.Entity.UpLoad;
using MaterialTraceability.SqlSugar;
using MaterialTraceability.SqlSugar.ServiceImpl;
using MaterialTraceability.WebService;
using MaterialTraceability.WebService.MiFirstOperationForsfcServiceService;
using MaterialTraceability.WebService.MiReleaseSfcWithActivityServiceService;
using MaterialTraceability.WebService.Param;
using MaterialTraceability.WebService.ProcessLotServiceWSService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MaterialTraceability.Business.Impl
{
/// <summary>
/// 涂布信号逻辑处理
/// </summary>
public class TBSignalReadBusiness : ISignalReadFunction
{
// INIFile配置文件
private INIFile inifile = new INIFile(System.Environment.CurrentDirectory + "/MesConfig/App.InI");
/// <summary>
/// 日志刷新
/// </summary>
/// <param name="type">日志内容</param>
/// <param name="massage"></param>
public delegate void LogRefresh(LogType logType, string massage);
public static event LogRefresh LogRefreshEvent;
/// <summary>
/// 视图层数据刷新
/// </summary>
/// <param name="viewModelDto"></param>
public delegate void ViewModelRefresh(ViewModelDto viewModelDto);
public static event ViewModelRefresh ViewModelRefreshEvent;
/// <summary>
/// 涂布工单下达获取结果事件
/// </summary>
/// <param name="result"></param>
/// <param name="sfc"></param>
public delegate void GetSFCByMes(bool result, string sfc);
public static event GetSFCByMes GetSFCByMesEvent;
/// <summary>
/// 涂布结束流程
/// </summary>
/// <param name="sfc"></param>
/// <param name="proDownRecord"></param>
public delegate void EndProduction(int ea, ProShaftInfo proDownRecord);
public static event EndProduction EndProductionEvent;
/// <summary>
/// 清空流程界面
/// </summary>
public delegate void ClearViewRefresh();
public static event ClearViewRefresh ClearViewRefreshEvent;
/// <summary>
/// 异常处理流程刷新
/// </summary>
public delegate void TBAlarmRecordRefresh();
public static event TBAlarmRecordRefresh TBAlarmRecordRefreshEvent;
/// <summary>
/// PLC信号事件
/// </summary>
/// <param name="status"></param>
/// <param name="position"></param>
public delegate void SignalReadInvoke(int status, int position);
/// <summary>
/// RFID读写器业务
/// </summary>
private EquipBusiness equipBusiness = new EquipBusiness();
/// <summary>
/// Mes WebService接口
/// </summary>
private IMesWebServices MesWebServices = new MesWebServicesImpl();
//卷轴信息
private IBaseServices<ProShaftInfo> shaftInfoServices = new BaseServices<ProShaftInfo>();
//收卷记录
private IBaseServices<ProDownRecord> downRecordServices = new BaseServices<ProDownRecord>();
private IBaseServices<SysClient> sysClientServices = new BaseServices<SysClient>();
private IBaseServices<ProUpRecord> upRecordServices = new BaseServices<ProUpRecord>();
private MesAlarmInfo alarmInfo = new MesAlarmInfo();
private PlcBusiness plcBusiness = new PlcBusiness();
private UpLoadBusiness upLoadBusiness = UpLoadBusiness.Instance;
private AppConfigDto appConfig = AppConfigDto.Instance;
/// <summary>
/// 放卷位涨紧
/// </summary>
/// <param name="position"></param>
public void UpMaterialBegin(int position)
{
string logStr = position == 3 ? "A放卷轴" : "B放卷轴";
try
{
LogRefreshEvent?.Invoke(LogType.PlcLog, $"{logStr}涨紧信号触发成功");
ProEquip proEquip = equipBusiness.Equiplist.Where(x => x.positionId == position).FirstOrDefault();
if (proEquip == null)
{
LogRefreshEvent?.Invoke(LogType.AlarmLog, $"获取{logStr}读写器设备信息异常");
return;
}
string epc = equipBusiness.ReadEPCByAntana(proEquip.equipId);
epc = epc.Replace("\0", "").Trim();
SaveReadRecord(proEquip, epc);
if (StringExtension.IsBlank(epc))
{
plcBusiness.writePlc(appConfig.TbAddress., 1);
plcBusiness.writePlc(position == 3 ? appConfig.TbAddress.RFID : appConfig.TbAddress.RFID, 1);
LogHelper.Info($"{logStr}RFID条码信息读取失败下发PLC报警");
LogRefreshEvent?.Invoke(LogType.AlarmLog, $"{logStr}RFID条码信息读取失败");
ViewModelRefreshEvent?.Invoke(new ViewModelDto()
{
rfidInfo = new RfidInfoDto()
{
rfid = "",
sfc = "",
ea = "",
position = position,
},
plcStatus = true,
});
return;
}
LogHelper.Info($"{logStr}RFID条码信息读取成功{epc}");
LogRefreshEvent?.Invoke(LogType.RfidLog, $"{logStr}RFID条码信息读取成功,RFID为{epc}");
//判断RFID标签是否重复
LogHelper.Info($"{logStr}判断RFID标签是否重复");
if (BusinessHelper.UpRfidIsRecur(epc, position).Result)
{
//判断是否已经生产结束
if (UpMaterialIsEndProduction(epc).Result)
{
plcBusiness.writePlc(appConfig.LyAddress.RFID, 1);
LogRefreshEvent?.Invoke(LogType.AlarmLog, String.Format("当前读取的RFID{0},已经生产结束不允许再次上料", epc));
LogHelper.Info(String.Format("当前读取的RFID{0},已经生产结束不允许再次上料", epc));
return;
}
else
{
Expression<Func<ProUpRecord, bool>> exp = s1 => true;
Expression<Func<ProUpRecord, object>> order = (x) => x.RecordTime;
ProUpRecord upRecord = upRecordServices.QueryFirst(exp, order, false).Result;
if (upRecord != null)
{
PlcBusiness.writeStrPlc(position == 3 ? appConfig.TbAddress.ASFC : appConfig.TbAddress.BSFC, upRecord.Sfc);
ViewModelRefreshEvent?.Invoke(new ViewModelDto()
{
rfidInfo = new RfidInfoDto()
{
rfid = epc,
sfc = upRecord.Sfc,
position = position,
},
plcStatus = true,
});
}
LogHelper.Info($"{logStr}RFID读取到的条码{epc};与前一读取相同并且生产未结束,可以继续生产");
LogRefreshEvent?.Invoke(LogType.RfidLog, $"{logStr}RFID读取到的条码{epc};与前一读取相同并且生产未结束,可以继续生产");
LogHelper.Info("冷压放卷流程处理成功");
//plcBusiness.writePlc(appConfig.LyAddress.放卷OK, 0);
return;
}
}
//读取数据刷新
ViewModelRefreshEvent?.Invoke(new ViewModelDto()
{
rfidInfo = new RfidInfoDto()
{
rfid = epc,
//sfc = "",
position = position,
},
plcStatus = true,
});
FJMesBegin(position, epc, true);
}
catch (Exception ex)
{
LogHelper.Info($"{logStr}放卷涨紧流程RFID逻辑处理异常:{ex.Message}");
plcBusiness.writePlc(position == 3 ? appConfig.TbAddress.RFID : appConfig.TbAddress.RFID, 1);
}
}
/// <summary>
/// 放卷位结束
/// </summary>
/// <param name="position"></param>
public async void UpMaterialEnd(int position)
{
string logStr = position == 3 ? "A放卷轴" : "B放卷轴";
try
{
LogRefreshEvent?.Invoke(LogType.PlcLog, $"{logStr}结束信号触发成功");
ProShaftInfo shaftInfo = await this.GetShaftInfoByPosition(position);
if (shaftInfo == null)
{
LogRefreshEvent?.Invoke(LogType.RfidLog, $"{logStr}放卷结束,获取卷轴绑定的信息为空");
return;
}
Expression<Func<ProUpRecord, bool>> upExp = s1 => true;
upExp = upExp.And(x => x.Sfc == shaftInfo.bindSfc && x.Rfid == shaftInfo.bindRfid && x.IsProduction == 0);
Expression<Func<ProUpRecord, object>> upOrder = (x) => x.RecordTime;
ProUpRecord upRecord = await upRecordServices.QueryFirst(upExp, upOrder, false);
if (upRecord == null)
{
LogRefreshEvent?.Invoke(LogType.AlarmLog, $"{logStr}放卷结束,获取上料信息为空");
return;
}
//更新放卷信息
upRecord.endTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
upRecord.IsProduction = 1;
upRecord.isFinish = 1;
await upRecordServices.Update(upRecord);
LogRefreshEvent?.Invoke(LogType.RfidLog, "生成放卷信息");
shaftInfo.bindRfid = string.Empty;
shaftInfo.bindSfc = string.Empty;
shaftInfo.bindEaValue = string.Empty;
shaftInfo.bindTime = string.Empty;
await shaftInfoServices.Update(shaftInfo);
plcBusiness.writePlc(appConfig.TbAddress., 0);
}
catch (Exception ex)
{
LogHelper.Info($"{logStr}放卷结束流程RFID逻辑处理异常:{ex.Message}");
}
}
///add by yinzf
/// <summary>
///
/// </summary>
/// <param name="position"></param>
public void UpBegin(int position)
{
string logStr = position == 3 ? "A放卷轴" : "B放卷轴";
try
{
LogRefreshEvent?.Invoke(LogType.PlcLog, $"{logStr}开始信号触发成功");
plcBusiness.writePlc(appConfig.TbAddress., 1);
}
catch(Exception ex)
{
LogHelper.Info($"{logStr}放卷结束流程RFID逻辑处理异常:{ex.Message}");
}
}
/// <summary>
/// 放卷涨紧MES处理
/// </summary>
/// <param name="position"></param>
/// <param name="epc"></param>
/// <param name="auto"></param>
public async void FJMesBegin(int position, string epc, bool auto)
{
string logStr = position == 3 ? "A放卷轴" : "B放卷轴";
string sfc = "";
string qty = "";
try
{
if (!auto)
{
plcBusiness.writePlc(position == 3 ? appConfig.TbAddress.RFID : appConfig.TbAddress.RFID, 0);
plcBusiness.writePlc(position == 3 ? appConfig.TbAddress.MES : appConfig.TbAddress.MES, 0);
}
#region 这里进行MES操作
LogHelper.Info("调用MES首工序获取SFC接口");
LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES首工序获取SFC接口");
LogRefreshEvent?.Invoke(LogType.RfidLog, "调用MES首工序获取SFC接口");
//调MES首工序获取SFC接口
MiFirstOperationForsfcServiceServiceParam miFirstOperationForsfcServiceServiceParam = new MiFirstOperationForsfcServiceServiceParam()
{
url = inifile.IniReadValue("MiFirstOperationForsfcServiceServiceParam", "url"),
site = inifile.IniReadValue("MiFirstOperationForsfcServiceServiceParam", "site"),
sfc = "",
processLot = epc,
operation = appConfig.operation,
operationRevision = inifile.IniReadValue("MiFirstOperationForsfcServiceServiceParam", "operationRevision"),
resource = appConfig.resource,
user = inifile.IniReadValue("MiFirstOperationForsfcServiceServiceParam", "user"),
activity = inifile.IniReadValue("MiFirstOperationForsfcServiceServiceParam", "activity"),
modeProcessSfc = inifile.IniReadValue("MiFirstOperationForsfcServiceServiceParam", "modeProcessSfc"),
loginUser = "",
password = "",
};
LogHelper.Info("MES首工序获取SFC接口请求参数" + JsonChange.ModeToJson(miFirstOperationForsfcServiceServiceParam));
miFirstOperationForsfcResponse firstOperationForsfcResponse = new miFirstOperationForsfcResponse();
if (appConfig.isMesFlag == 1)
{
DateTime beginTime = DateTime.Now;
try
{
firstOperationForsfcResponse = MesWebServices.iMiFirstOperationForsfcServiceService(miFirstOperationForsfcServiceServiceParam);
LogHelper.Info("MES首工序获取SFC接口返回参数" + JsonChange.ModeToJson(firstOperationForsfcResponse));
//判断返回结果
if (firstOperationForsfcResponse.@return.code > 0)
{
LogHelper.Info("MES首工序获取SFC接口请求失败" + firstOperationForsfcResponse.@return.message);
plcBusiness.writePlc(appConfig.TbAddress., 1);
plcBusiness.writePlc(appConfig.TbAddress.MES, firstOperationForsfcResponse.@return.code);
LogHelper.Info("MES首工序获取SFC接口调用失败" + firstOperationForsfcResponse.@return.message);
LogRefreshEvent?.Invoke(LogType.RfidLog, "MES首工序获取SFC接口调用失败");
LogRefreshEvent?.Invoke(LogType.MesLog, "MES首工序获取SFC接口调用失败" + upLoadBusiness.GetMesMessage(firstOperationForsfcResponse.@return.code, firstOperationForsfcResponse.@return.message));
LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES首工序获取SFC接口调用失败" + upLoadBusiness.GetMesMessage(firstOperationForsfcResponse.@return.code, firstOperationForsfcResponse.@return.message));
LogRefreshEvent?.Invoke(LogType.PlcLog, "MES首工序获取SFC接口调用失败");
return;
}
sfc = firstOperationForsfcResponse.@return.sfc;
qty = firstOperationForsfcResponse.@return.qty;
LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("MES首工序获取SFC接口调用成功SFC{0}EA{1}", sfc, qty));
LogHelper.Info(String.Format("MES首工序获取SFC接口调用成功SFC{0}EA{1}", sfc, qty));
}
catch (Exception ex)
{
LogHelper.Info("调用MES首工序获取SFC接口异常" + ex.Message);
LogRefreshEvent?.Invoke(LogType.AlarmLog, "调用MES首工序获取SFC接口异常" + ex.Message);
LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES首工序获取SFC接口异常" + ex.Message);
WebServiceLog.saveMiFirstOperationForsfcServiceService(miFirstOperationForsfcServiceServiceParam, null
, beginTime, ex.Message);
plcBusiness.writePlc(appConfig.TbAddress., 1);
plcBusiness.writePlc(appConfig.TbAddress.MES, 1);
return;
}
}
else
{
sfc = System.Guid.NewGuid().ToString("N").Substring(0, 14);
qty = "2000";
LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("MES首工序获取SFC接口调用成功SFC{0}EA{1}", sfc, qty));
}
#endregion
//向PLC写入SFC膜卷号
PlcBusiness.writeStrPlc(position == 3 ? appConfig.TbAddress.ASFC : appConfig.TbAddress.BSFC, sfc);
ViewModelRefreshEvent?.Invoke(new ViewModelDto()
{
rfidInfo = new RfidInfoDto()
{
rfid = epc,
sfc = sfc,
position = position,
ea = qty,
},
plcStatus = true,
});
//实时绑定卷轴与RFID信息
LogHelper.Info($"{logStr}绑定放卷轴与RFID:{epc};获取卷轴信息");
ProShaftInfo shaftInfo = await this.GetShaftInfoByPosition(position);
if (shaftInfo == null || StringExtension.IsBlank(shaftInfo.processId))
{
LogRefreshEvent?.Invoke(LogType.RfidLog, $"{logStr}绑定卷轴与RFID获取卷轴信息为空");
LogRefreshEvent?.Invoke(LogType.AlarmLog, $"{logStr}绑定卷轴与RFID获取卷轴信息为空");
LogHelper.Info($"{logStr}绑定卷轴与RFID获取卷轴信息为空");
return;
}
LogHelper.Info($"{logStr}获取卷轴信息为:" + JsonChange.ModeToJson(shaftInfo));
shaftInfo.bindRfid = epc;
shaftInfo.bindSfc = sfc;
shaftInfo.bindEaValue = qty;
shaftInfo.bindTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
await shaftInfoServices.Update(shaftInfo);
//本地保存SFC,上料记录
ProUpRecord upRecord = new ProUpRecord()
{
Id = System.Guid.NewGuid().ToString(),
MachineId = appConfig.machineId,
PositionId = position,
Rfid = epc,
Sfc = sfc,
eaValue = StringChange.ParseToInt(qty),
IsProduction = 0,
beginTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
RecordTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
};
await upRecordServices.Add(upRecord);
upLoadBusiness.SaveUpRecord(upRecord);
LogHelper.Info($"{logStr}放卷流程处理成功");
plcBusiness.writePlc(position == 3 ? appConfig.TbAddress.AOK : appConfig.TbAddress.BOK, 1);
}
catch (Exception ex)
{
LogHelper.Info($"{logStr}放卷流程MES逻辑处理异常:{ex.Message}");
plcBusiness.writePlc(position == 3 ? appConfig.TbAddress.RFID : appConfig.TbAddress.RFID, 1);
}
}
/// <summary>
/// 收卷位涨紧
/// </summary>
/// <param name="position"></param>
public void DownMaterialBegin(int position)
{
string logStr = position == 1 ? "A轴" : "B轴";
#region 未登录不让涨紧生产,便于记录生产者
/*if (StringExtension.IsBlank(ConfigHelper.GetConfig("roleId")))
{
MessageBox.Show("请先登录再开始生产");
LogHelper.Info("请先登录再开始生产");
LogRefreshEvent?.Invoke(LogType.AlarmLog, "请先登录再开始生产");
return;
}*/
#endregion
//string sfc = "";
try
{
//获取当前涨紧卷轴 A轴1B轴2
LogRefreshEvent?.Invoke(LogType.PlcLog, logStr + "收卷涨紧触发成功");
LogHelper.Info(logStr + "收卷涨紧触发成功");
LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("开始读取{0}卷筒RFID物料信息",logStr));
LogHelper.Info(String.Format("开始读取{0}卷筒RFID物料信息", logStr));
//读取卷筒RFID物料信息
ProEquip proEquip = equipBusiness.Equiplist.Where(x => x.positionId == position).FirstOrDefault();
if(proEquip == null)
{
LogRefreshEvent?.Invoke(LogType.RfidLog, "获取" + logStr + "读写器设备信息异常");
return;
}
string epc = equipBusiness.ReadEPCByAntana(proEquip.equipId);
//string epc = System.Guid.NewGuid().ToString("N").Substring(0,14);
epc = epc.Replace("\0", "").Trim();
SaveReadRecord(proEquip, epc);
if (StringExtension.IsBlank(epc))
{
//读取失败控制PLC气胀轴
plcBusiness.writePlc(appConfig.TbAddress., 1);
//写入报警
plcBusiness.writePlc(appConfig.TbAddress.RFID, 1);
//写入转塔是否可以旋转
plcBusiness.writePlc(appConfig.TbAddress., 0);
LogHelper.Info("RFID条码信息读取失败下发气胀轴泄气D9608写1下发读取失败报警信息D9610写1");
LogRefreshEvent?.Invoke(LogType.RfidLog, logStr + "RFID条码信息读取失败");
LogRefreshEvent?.Invoke(LogType.AlarmLog, logStr + "RFID条码信息读取失败");
ViewModelRefreshEvent?.Invoke(new ViewModelDto()
{
rfidInfo = new RfidInfoDto()
{
rfid = "",
sfc = "",
ea = "",
position = position,
},
plcStatus = true,
});
return;
}
LogHelper.Info("收卷位设备:" + proEquip.equipIp + "涨紧信号读取成功:" + epc);
LogRefreshEvent?.Invoke(LogType.RfidLog, logStr + "RFID条码信息读取成功" + epc);
lock(string.Empty)
{
LogHelper.Info("判断RFID标签是否重复");
if (BusinessHelper.DownRfidIsRecur(epc,position).Result)
{
LogHelper.Info(logStr + "RFID读取到的条码" + epc + "与前一读取相同不做MES处理");
LogRefreshEvent?.Invoke(LogType.RfidLog, logStr + "RFID读取到的条码" + epc + "与前一读取相同不做MES处理");
LogRefreshEvent?.Invoke(LogType.AlarmLog, logStr + "RFID读取到的条码" + epc + "与前一读取相同不做MES处理");
plcBusiness.writePlc(appConfig.TbAddress., 1);
return;
}
MesBegin(position, epc, true);
}
}
catch (Exception ex)
{
LogHelper.Error("涂布工序收卷位涨紧逻辑处理异常",ex);
}
}
/// <summary>
/// 收卷位结束
/// </summary>
/// <param name="position"></param>
public async void DownMaterialEnd(int position)
{
string logStr = position == 1 ? "A轴" : "B轴";
try
{
LogRefreshEvent?.Invoke(LogType.PlcLog, logStr + "收卷结束信号触发成功");
LogHelper.Info(logStr + "收卷结束信号触发成功");
//获取收卷轴绑定的RFID条码信息,取最新数据
Expression<Func<ProShaftInfo, bool>> exp = s1 => true;
exp = exp.And(x => x.positionId == position.ToString() && x.processId == appConfig.processId);
Expression<Func<ProShaftInfo, object>> order = (x) => x.bindTime;
ProShaftInfo shaftInfo = await shaftInfoServices.QueryFirst(exp, order, false);
if (StringExtension.IsBlank(shaftInfo.bindRfid))
{
LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("{0}收卷完工获取绑定信息为空不进入结束流程", logStr));
LogRefreshEvent?.Invoke(LogType.AlarmLog, String.Format("{0}收卷完工获取绑定信息为空不进入结束流程", logStr));
LogHelper.Info(String.Format("{0}收卷完工获取绑定信息为空不进入结束流程", logStr));
return;
}
LogHelper.Info(String.Format("{0}当前绑定的物料信息为:{1}", logStr, JsonChange.ModeToJson(shaftInfo)));
//下发禁止下料信号
LogRefreshEvent?.Invoke(LogType.PlcLog, logStr + "收卷结束,下发禁止下料信号");
int eaValue = PlcBusiness.readPlc(appConfig.TbAddress.);
LogRefreshEvent.Invoke(LogType.PlcLog, "读取收卷米数:" + eaValue);
LogHelper.Info("读取设备收卷米数:" + eaValue);
string membraneLength = GetSysConfigList("SysConfig").Where(x => x.paramKey == "membraneLength").FirstOrDefault().paramValue;
string volumesNumber = GetSysConfigList("SysConfig").Where(x => x.paramKey == "volumesNumber").FirstOrDefault().paramValue;
LogHelper.Info("获取设备膜长:"+ membraneLength+";系数:"+ volumesNumber);
eaValue = Convert.ToInt32(Convert.ToDouble(eaValue) / Convert.ToDouble(membraneLength) * Convert.ToDouble(volumesNumber));
LogRefreshEvent.Invoke(LogType.PlcLog, "读取设备收卷EA值:" + eaValue);
LogHelper.Info("读取设备收卷EA值" + eaValue);
LogHelper.Info("日志排查进入收卷完工操作前打印绑定信息shaftInfo:" + JsonChange.ModeToJson(shaftInfo));
//收卷完工操作
EndProductionEvent?.Invoke(eaValue, shaftInfo);
//刷新异常处理流程
TBAlarmRecordRefreshEvent?.Invoke();
}
catch (Exception ex)
{
LogHelper.Error("涂布工序收卷位结束逻辑处理异常", ex);
}
}
/// <summary>
/// 解绑RFID与SFC
/// </summary>
/// <param name="rfidStr"></param>
private void UnBindRfidAndSfc(int position,string rfidStr)
{
//获取当前RFID是否绑定
string sfcStr = "";
DateTime beginTime = new DateTime();
ProcessLotServiceWSServiceParam processLotServiceWSServiceParam = new ProcessLotServiceWSServiceParam()
{
//url = "http://lymesa.catlbattery.com:8103/manufacturing-papiservices/ProcessLotServiceWSService?wsdl",
//site = "2100",
url = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "url"),
site = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "site"),
processlotref = String.Format("ProcessLotBO:2100,{0}", rfidStr)
};
try
{
LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES接口获取RFID绑定的SFC");
LogHelper.Info("MES获取膜卷号接口请求参数" + JsonChange.ModeToJson(processLotServiceWSServiceParam));
if (appConfig.isMesFlag == 1)
{
readProcessLotResponse readProcessLotResponse = MesWebServices.readProcessLot(processLotServiceWSServiceParam);
LogHelper.Info("MES获取膜卷号接口返回参数" + JsonChange.ModeToJson(readProcessLotResponse));
if (readProcessLotResponse.Response.processLotMemberList != null)
{
sfcStr = readProcessLotResponse.Response.processLotMemberList[0].memberContext.Substring(11);
LogHelper.Info("RFID条码" + rfidStr + "绑定的SFC条码为" + sfcStr);
LogRefreshEvent?.Invoke(LogType.MesLog, "RFID条码" + rfidStr + "绑定的SFC条码为" + sfcStr);
}
}
else
{
sfcStr = System.Guid.NewGuid().ToString("N").Substring(0, 14);
}
}
catch (Exception ex)
{
LogHelper.Info("MES获取膜卷号接口调用异常" + ex.Message);
LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES获取膜卷号接口调用异常" + ex.Message);
WebServiceLog.saveReadProcessLot(processLotServiceWSServiceParam, null, beginTime, ex.Message);
return;
}
if (!StringExtension.IsBlank(sfcStr))
{
ProcessLotServiceWSServiceParam lotServiceWSServiceParam = new ProcessLotServiceWSServiceParam()
{
url = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "url"),
site = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "site"),
processlotref = "ProcessLotBO:2100," + rfidStr,
memberlist = new string[] { "SFCBO:2100," + sfcStr }
};
LogHelper.Info("MES解绑接口请求参数" + JsonChange.ModeToJson(lotServiceWSServiceParam));
beginTime = DateTime.Now;
try
{
if (appConfig.isMesFlag == 1)
{
removeMemberResponse removeMember = MesWebServices.iRemoveMember(lotServiceWSServiceParam);
LogHelper.Info("MES解绑接口返回参数" + JsonChange.ModeToJson(removeMember));
}
}
catch (Exception ex)
{
WebServiceLog.saveRemoveMember(processLotServiceWSServiceParam, null, beginTime, ex.Message);
LogRefreshEvent?.Invoke(LogType.MesLog, String.Format("解绑接口调用异常:{0}", ex.Message));
LogRefreshEvent?.Invoke(LogType.AlarmLog, String.Format("RFID条码{0}解绑失败:{1}!!!", rfidStr, ex.Message));
return;
}
}
else
{
LogHelper.Info("RFID条码" + rfidStr + "未绑定SFC信息");
LogRefreshEvent?.Invoke(LogType.RfidLog, "RFID条码" + rfidStr + "未绑定SFC信息");
}
}
/// <summary>
/// 卷筒涨紧MES处理信号
/// </summary>
/// <param name="postion"></param>
/// <param name="epc"></param>
/// <param name="auto">是否是自动读取如果不是自动读取需要把PLC信号清掉</param>
public async void MesBegin(int position, string epc, bool auto)
{
string logStr = position == 1 ? "A轴" : "B轴";
string sfc = "";
///把之前的信号清除了,但是现在还有问题,现在泄气以后,
///现场应该还要再涨紧,还会给我信号
if (!auto)
{
//清除泄气信号
plcBusiness.writePlc(appConfig.TbAddress., 0);
//清除报警
plcBusiness.writePlc(appConfig.TbAddress.RFID, 0);
}
try
{
#region Add By wenjy 2022-09-20 获取工单信息,判断是否需要更换工单
if (!ShopOrderAlarm(position))
{
//MES接口返回异常控制PLC气胀轴写1泄气
plcBusiness.writePlc(appConfig.TbAddress., 1);
//写入报警
plcBusiness.writePlc(appConfig.TbAddress.MES, 1);
return;
}
#endregion
//调用MES接口获取SFC
#region Update By wenjy 2022-09-20 涂布工单下达逻辑修改判断第一位不为L时重新获取
sfc = GetSFC(position);
if (StringExtension.IsBlank(sfc))
{
return;
}
if (sfc.Substring(0, 1) != "L")
{
sfc = GetSFC(position);
if (StringExtension.IsBlank(sfc))
{
return;
}
}
#endregion
LogHelper.Info("涂布工单下达接口调用成功SFC膜卷号为" + sfc);
LogRefreshEvent?.Invoke(LogType.MesLog, "MES涂布工单下达接口调用成功,膜卷号:" + sfc);
GetSFCByMesEvent?.Invoke(true, sfc);
WriteSfcAndEpc(position, sfc, epc);
ViewModelRefreshEvent?.Invoke(new ViewModelDto()
{
rfidInfo = new RfidInfoDto()
{
rfid = epc,
position = position,
sfc = sfc,
ea = "",
},
plcStatus = true,
});
LogHelper.Info("本地保存RFID及膜卷号信息生成收卷记录");
//实时绑定卷轴与RFID信息
LogHelper.Info(String.Format("绑定{0}卷轴与RFID:{1}获取卷轴信息", logStr, epc));
Expression<Func<ProShaftInfo, bool>> exp = s1 => true;
exp = exp.And(x => x.positionId == position.ToString() && x.processId == appConfig.processId);
Expression<Func<ProShaftInfo, object>> order = (x) => x.bindTime;
ProShaftInfo shaftInfo = await shaftInfoServices.QueryFirst(exp, order, true);
if (shaftInfo == null)
{
LogRefreshEvent?.Invoke(LogType.RfidLog, "绑定卷轴与RFID条码获取卷轴信息为空");
LogRefreshEvent?.Invoke(LogType.AlarmLog, "绑定卷轴与RFID条码获取卷轴信息为空");
LogHelper.Info("绑定卷轴与RFID获取卷轴信息为空");
return;
}
LogHelper.Info("获取卷轴信息为:" + JsonChange.ModeToJson(shaftInfo));
shaftInfo.bindRfid = epc;
shaftInfo.bindSfc = sfc;
shaftInfo.bindTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
await shaftInfoServices.Update(shaftInfo);
LogHelper.Info("本地绑定RFID" + epc + ",SFC" + sfc);
//PLC允许转塔 D9602写1
plcBusiness.writePlc(appConfig.TbAddress., 1);
//添加下料记录
ProDownRecord downRecord = new ProDownRecord()
{
Id = System.Guid.NewGuid().ToString("N"),
MachineId = appConfig.machineId,
PositionId = position,
Rfid = epc,
Sfc = sfc,
IsProduction = 0,
beginTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
RecordTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
};
await downRecordServices.Add(downRecord);
upLoadBusiness.SaveDownRecord(downRecord);
}
catch (Exception e)
{
LogHelper.Info(e.ToString());
}
}
private void WriteSfcAndEpc(int position,string sfcStr,string rfidStr)
{
if (position == 1)
{
LogHelper.Info("将SFC与RFID写入PLC地址");
PlcBusiness.writeStrPlc(appConfig.TbAddress.A, sfcStr);
PlcBusiness.writeStrPlc(appConfig.TbAddress.A, rfidStr);
LogRefreshEvent?.Invoke(LogType.PlcLog, "将SFC与RFID写入PLC地址");
}
else
{
LogHelper.Info("将SFC与RFID写入PLC地址");
PlcBusiness.writeStrPlc(appConfig.TbAddress.B, sfcStr);
PlcBusiness.writeStrPlc(appConfig.TbAddress.B, rfidStr);
LogRefreshEvent?.Invoke(LogType.PlcLog, "将SFC与RFID写入PLC地址");
}
}
/// <summary>
/// 涂布工单下达
/// </summary>
/// <returns></returns>
private string GetSFC(int position)
{
string sfc = "";
LogHelper.Info("调用MES涂布工单下达接口");
LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES涂布工单下达接口");
//调MES涂布工单下达接口获取SFC
MiReleaseSfcWithActivityServiceServiceParam miReleaseSfcWithActivityServiceServiceParam = new MiReleaseSfcWithActivityServiceServiceParam()
{
url = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam","url"),
site = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "site"),
user = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "user"),
operation = appConfig.operation,
operationRevision = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "operationRevision"),
activityId = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "activity"),
Resource = appConfig.resource,
sfcQty = 1,
modeProcessSfc = modeProcessSFC.MODE_START_SFC, //MODE_START_SFC
isCarrierType = false,
loginUser = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "loginUser"),
password = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "password"),
};
DateTime beginTime = DateTime.Now;
try
{
LogHelper.Info("涂布工单下达接口请求参数:" + JsonChange.ModeToJson(miReleaseSfcWithActivityServiceServiceParam));
if (appConfig.isMesFlag == 1)
{
miReleaseSfcWithActivityResponse releaseSfcWithActivityResponse = MesWebServices.iMiReleaseSfcWithActivityServiceService(miReleaseSfcWithActivityServiceServiceParam);
LogHelper.Info("涂布工单下发接口返回参数:" + JsonChange.ModeToJson(releaseSfcWithActivityResponse));
if (releaseSfcWithActivityResponse.@return.code > 0)
{
LogRefreshEvent?.Invoke(LogType.MesLog, "MES涂布工单获取失败:" + upLoadBusiness.GetMesMessage(releaseSfcWithActivityResponse.@return.code, releaseSfcWithActivityResponse.@return.message));
LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES涂布工单单获取:" + upLoadBusiness.GetMesMessage(releaseSfcWithActivityResponse.@return.code, releaseSfcWithActivityResponse.@return.message));
GetSFCByMesEvent?.Invoke(false, "");
//MES接口返回异常控制PLC气胀轴写1泄气
plcBusiness.writePlc(appConfig.TbAddress., 1);
//写入报警
plcBusiness.writePlc(appConfig.TbAddress.MES, 1);
//写入转塔是否可以旋转
plcBusiness.writePlc(appConfig.TbAddress., 0);
LogHelper.Info("涂布工单下达接口获取失败:" + releaseSfcWithActivityResponse.@return.message + "下发气胀轴泄气D9608下发MES接口返回异常报警D9612");
return "";
}
sfc = releaseSfcWithActivityResponse.@return.sfcArray[0].sfc;
}
else
{
sfc = System.Guid.NewGuid().ToString("N").Substring(0, 14);
}
return sfc;
}
catch (Exception ex)
{
WebServiceLog.saveMiReleaseSfcWithActivityServiceService(miReleaseSfcWithActivityServiceServiceParam, null, beginTime, ex.Message);
LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES涂布工单下达接口调用异常:" + ex.Message);
LogRefreshEvent?.Invoke(LogType.MesLog, "MES涂布工单下达接口调用异常:" + ex.Message);
GetSFCByMesEvent?.Invoke(false, "");
//读取失败控制PLC气胀轴
plcBusiness.writePlc(appConfig.TbAddress., 1);
//写入报警
plcBusiness.writePlc(appConfig.TbAddress.MES, 1);
//写入转塔是否可以旋转
plcBusiness.writePlc(appConfig.TbAddress., 0);
return "";
}
}
/// <summary>
/// 工单预警
/// </summary>
/// <returns></returns>
private bool ShopOrderAlarm(int position)
{
try
{
//获取工单预警设置
var shopOrderConfig = GetSysConfigList("ShopOrderAlarm");
if (shopOrderConfig.Count == 0)
{
LogRefreshEvent?.Invoke(LogType.AlarmLog, "获取工单预警设置信息为空");
LogHelper.Info("获取工单预警设置信息为空");
return false;
}
string shopOrderStr = shopOrderConfig.Where(x => x.paramKey == "ShopOrder").FirstOrDefault().paramValue;
string orderAlarmAmount = shopOrderConfig.Where(x => x.paramKey == "OrderAlarmAmount").FirstOrDefault().paramValue;
FindShopRequestParam findShopRequestParam = new FindShopRequestParam()
{
url = inifile.IniReadValue("FindShopRequestParam","url"),
site = inifile.IniReadValue("FindShopRequestParam", "site"),
shopOrder = String.Format("ShopOrderBO:2100,{0}", shopOrderStr)
};
LogHelper.Info("调用MES获取工单产量信息接口请求参数"+ JsonChange.ModeToJson(findShopRequestParam));
var info = MesWebServices.findShopOrder(findShopRequestParam);
LogHelper.Info("调用MES获取工单产量信息接口返回参数"+JsonChange.ModeToJson(info));
var quantityOrderd = info.Response.quantityOrdered; //工单总数量
var quantityReleased = info.Response.quantityReleased; //已下达数量
if (Convert.ToDecimal(orderAlarmAmount) < quantityOrderd - quantityReleased)
{
return true;
}
LogRefreshEvent?.Invoke(LogType.AlarmLog, "工单超产,及时更换工单");
return false;
}catch(Exception ex)
{
LogRefreshEvent?.Invoke(LogType.AlarmLog, "工单预警判断异常:"+ex.Message);
return false;
}
}
/// <summary>
/// 强制下料
/// </summary>
/// <param name="position"></param>
public async void ForceDown(int position)
{
try
{
///放卷强制下料
if(position > 2)
{
string logstr = position == 3 ? "A放卷轴" : "B放卷轴";
LogRefreshEvent?.Invoke(LogType.PlcLog, $"{logstr}强制下料信号触发成功");
UpMaterialEnd(position);
plcBusiness.writePlc(appConfig.TbAddress., 0);
return;
}
string logStr = position == 1 ? "A轴" : "B轴";
LogHelper.Info(logStr + "强制下料信号触发,下发下料信号");
LogRefreshEvent?.Invoke(LogType.PlcLog, logStr + "强制下料信号触发成功");
LogRefreshEvent?.Invoke(LogType.PlcLog, logStr + "下发下料信号");
plcBusiness.writePlc(appConfig.TbAddress., 0);
string bindSfc = "";
var shatInfo = await GetShaftInfoByPosition(position);
if(shatInfo == null)
{
LogHelper.Info("强制下料获取绑定信息为空");
return;
}
bindSfc = shatInfo.bindSfc;
LogRefreshEvent?.Invoke(LogType.PlcLog, String.Format("获取{0}绑定的SFC信息{1}", logStr, bindSfc));
//通过SFC获取下料信息
Expression<Func<ProDownRecord, bool>> exp = s1 => true;
exp = exp.And(x => x.Sfc == bindSfc && x.PositionId == position);
Expression<Func<ProDownRecord, object>> order = s1 => s1.RecordTime;
ProDownRecord downRecord = await downRecordServices.QueryFirst(exp, order, false);
if (downRecord == null)
{
TBAlarmRecordRefreshEvent?.Invoke();
LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format(logStr + "通过SFC{0}获取下料信息为空", bindSfc));
return;
}
downRecord.IsProduction = 3;
downRecord.endTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
if (downRecord.eaValue < 15)
{
int eaValue = PlcBusiness.readPlc(appConfig.TbAddress.);
LogRefreshEvent.Invoke(LogType.PlcLog, "读取收卷米数:" + eaValue);
LogHelper.Info("读取设备收卷米数:" + eaValue);
string membraneLength = GetSysConfigList("SysConfig").Where(x => x.paramKey == "membraneLength").FirstOrDefault().paramValue;
string volumesNumber = GetSysConfigList("SysConfig").Where(x => x.paramKey == "volumesNumber").FirstOrDefault().paramValue;
LogHelper.Info("获取设备膜长:" + membraneLength + ";系数:" + volumesNumber);
eaValue = Convert.ToInt32(Convert.ToDouble(eaValue) / Convert.ToDouble(membraneLength) * Convert.ToDouble(volumesNumber));
LogRefreshEvent.Invoke(LogType.PlcLog, "设备收卷EA值:" + eaValue);
LogHelper.Info("设备收卷EA值" + eaValue);
downRecord.eaValue = eaValue;
}
bool updateResult = await downRecordServices.Update(downRecord);
if (!updateResult)
{
TBAlarmRecordRefreshEvent?.Invoke();
LogRefreshEvent?.Invoke(LogType.RfidLog, "强制下料状态更新失败");
return;
}
LogRefreshEvent?.Invoke(LogType.RfidLog, "强制下料状态更新成功");
LogRefreshEvent?.Invoke(LogType.PlcLog, logStr + "强制下料完成");
ClearViewRefreshEvent?.Invoke();
//刷新异常处理流程状态
TBAlarmRecordRefreshEvent?.Invoke();
}
catch(Exception ex)
{
LogRefreshEvent?.Invoke(LogType.RfidLog, "强制下料信号处理异常" + ex.Message);
LogHelper.Error("强制下料信号处理异常", ex);
}
}
public async Task<ProShaftInfo> GetShaftInfoByPosition(int position)
{
try
{
string str = appConfig.processId;
Expression<Func<ProShaftInfo, bool>> exp = s1 => true;
exp = exp.And(x => x.positionId == position.ToString() && x.processId == str);
List<ProShaftInfo> result = await shaftInfoServices.Query(exp);
if (result != null || result.Count > 0)
{
ProShaftInfo shaftInfo = result.FirstOrDefault();
return shaftInfo;
}
return null;
}
catch (Exception ex)
{
LogRefreshEvent?.Invoke(LogType.RfidLog, "获取卷轴信息为空");
LogHelper.Info("获取卷轴信息异常:" + ex.Message);
return null;
}
}
/// <summary>
/// 收卷位开始信号
/// </summary>
/// <param name="position"></param>
public void DownBegin(int position)
{
string logStr = position == 1 ? "A轴" : "B轴";
try
{
LogHelper.Info(logStr + "收卷开始信号触发成功解绑RFID绑定的SFC条码");
LogRefreshEvent?.Invoke(LogType.PlcLog, logStr + "收卷开始信号触发成功");
LogRefreshEvent?.Invoke(LogType.RfidLog, logStr + "解绑RFID绑定的SFC条码");
//获取RFID条码信息
ProShaftInfo shaftInfo = this.GetShaftInfoByPosition(position).Result;
this.UnBindRfidAndSfc(position, shaftInfo.bindRfid);
}
catch (Exception ex)
{
LogHelper.Info(logStr + "收卷开始信号逻辑处理异常:" + ex.Message);
upLoadBusiness.SaveLogRecord(position, logStr + "收卷开始信号逻辑处理异常:" + ex.Message);
}
}
/// <summary>
/// 获取配置列表
/// </summary>
/// <returns></returns>
private List<SysClient> GetSysConfigList(string paramType)
{
try
{
Expression<Func<SysClient, bool>> exp = s1 => true;
if (StringExtension.IsNotBlank(paramType))
{
exp = exp.And(x => x.paramType == paramType);
}
exp = exp.And(x => x.processId == appConfig.processId);
List<SysClient> info = sysClientServices.Query(exp).Result;
return info;
}catch(Exception ex)
{
LogHelper.Error("获取配置列表异常", ex);
return null;
}
}
/// <summary>
/// 设备启动
/// </summary>
public void MachineStartUp()
{
throw new NotImplementedException();
}
private void SaveReadRecord(ProEquip equip, string rfidStr)
{
ProReadRecord readRecord = new ProReadRecord()
{
MachineID = equip.machineId,
EquipID = equip.equipId,
PositionID = equip.positionId,
Ant = StringChange.ParseToInt(equip.equipAnt),
ReadEPC = rfidStr,
Result = StringExtension.IsBlank(rfidStr) ? "0" : "1",
ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
};
upLoadBusiness.SaveReadRecord(readRecord);
}
/// <summary>
/// 放卷位物料是否结束生产
/// </summary>
/// <param name="epc"></param>
private async Task<bool> UpMaterialIsEndProduction(string rfidStr)
{
bool result = false;
Expression<Func<ProUpRecord, bool>> exp = s1 => true;
exp = exp.And(x => x.Rfid == rfidStr);
Expression<Func<ProUpRecord, object>> order = s1 => s1.RecordTime;
ProUpRecord upRecord = await upRecordServices.QueryFirst(exp, order, false);
if (upRecord != null)
{
if (StringExtension.IsBlank(upRecord.endTime))
{
LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("当前SFC{0}放卷结束时间为空,生产未结束", rfidStr));
result = false;
}
else
{
LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("当前SFC{0}放卷结束时间为:{1}", rfidStr, upRecord.endTime));
result = true;
}
}
return result;
}
}
}