|
|
using iWareSda.Common;
|
|
using iWareModel;
|
using System;
|
using System.Collections.Generic;
|
using System.Threading;
|
using iWareCommon.Utils;
|
using iWareCommon.Common.Globle;
|
using iWareCommon;
|
using iWareSda.Model;
|
|
|
namespace iWareSda
|
{
|
public class SrmEntity : IDevice
|
{
|
public SrmEntity()
|
{
|
this.View = new SrmView();
|
}
|
|
#region OPC相关
|
|
/// <summary>
|
/// 写的DB块
|
/// </summary>
|
public SrmDBForWrite DBBlockForWrite { get; set; }
|
|
/// <summary>
|
/// 读的DB块
|
/// </summary>
|
public SrmDBForRead DBBlockForRead { get; set; }
|
|
/// <summary>
|
/// 读取PLC实例
|
/// </summary>
|
public PLCService plcService { get; set; }
|
|
/// <summary>
|
/// 视图对象
|
/// </summary>
|
public SrmView View { get; set; }
|
|
|
#endregion
|
|
|
/// <summary>
|
/// 初始化数据
|
/// </summary>
|
public void InitData()
|
{
|
|
|
}
|
public SrmEntity(string srmName, int deviceId, SrmDBForWrite _dbBlockForWrite, SrmDBForRead _dbBlockForRead, PLCService _plcService)
|
{
|
this.View = new SrmView();
|
this.View.DeviceName = srmName;
|
this.View.DeviceId = deviceId;
|
plcService = _plcService;
|
DBBlockForWrite = _dbBlockForWrite;
|
DBBlockForRead = _dbBlockForRead;
|
}
|
|
|
#region 个性化方法
|
|
/// <summary>
|
/// 是否允许给堆垛机发送新任务
|
/// </summary>
|
/// <param name="srm"></param>
|
/// <returns></returns>
|
public bool IsAllowSendNewTaskToSrm()
|
{
|
Thread.Sleep(2000);//等待一秒钟 【EditBy shaocx,2022-03-26】
|
if (this.View.ModeName == "自动" && this.View.R_AlarmCode == 0 && (this.View.R_WarningDBList == null || this.View.R_WarningDBList.Count == 0)
|
&& this.View.StateName == "空闲")
|
{
|
return true;
|
}
|
return false;
|
}
|
|
|
/// <summary>
|
/// 重新格式化处理站点号
|
/// </summary>
|
/// <param name="sourcePlace"></param>
|
/// <param name="toPlace"></param>
|
public void ReSubStringPlace(ref string sourcePlace, ref string toPlace)
|
{//1-01-03-04 转换为 01-03-04
|
sourcePlace = sourcePlace.Substring(2, sourcePlace.Length - 2);
|
toPlace = toPlace.Substring(2, toPlace.Length - 2);
|
}
|
|
/// <summary>
|
/// 给堆垛机发送指令
|
/// </summary>
|
/// <param name="deviceId">堆垛机设备号</param>
|
/// <param name="taskId">任务号</param>
|
/// <param name="sourcePlace">起始位</param>
|
/// <param name="toPlace">目标位</param>
|
/// <param name="command">任务类型</param>
|
/// <param name="msg">错误消息</param>
|
/// <returns></returns>
|
public bool SendTask(ESrmCmd srmCmd, int deviceId, int taskId, string sourcePlace, string toPlace, short pallettype, out string msg)
|
{
|
try
|
{
|
msg = "";
|
if (!CanDoTask(deviceId, out msg, srmCmd))
|
{
|
return false;
|
}
|
|
//Z 排 X 列 Y层
|
//01-02-03
|
int sourceZ = 0, sourceX = 0, sourceY = 0;
|
if (srmCmd == ESrmCmd.库内搬运 || srmCmd == ESrmCmd.入库 || srmCmd == ESrmCmd.出库 || srmCmd == ESrmCmd.单取)
|
{
|
var arr_source = sourcePlace.Split('-');
|
//int sourceZ = int.Parse(sourcePlace.Substring(0, 2));
|
//int sourceX = int.Parse(sourcePlace.Substring(2, 4));
|
//int sourceY = int.Parse(sourcePlace.Substring(3, 2));
|
sourceZ = int.Parse(arr_source[0]);
|
sourceX = int.Parse(arr_source[1]);
|
sourceY = int.Parse(arr_source[2]);
|
ConvertPlaceToSrm(deviceId, ref srmCmd, true, sourcePlace, ref sourceZ, ref sourceX, ref sourceY);
|
}
|
|
|
var arr_to = toPlace.Split('-');
|
//int toZ = int.Parse(toPlace.Substring(0, 1));
|
//int toX = int.Parse(toPlace.Substring(1, 2));
|
//int toY = int.Parse(toPlace.Substring(3, 2));
|
int toZ = int.Parse(arr_to[0]);
|
int toX = int.Parse(arr_to[1]);
|
int toY = int.Parse(arr_to[2]);
|
ConvertPlaceToSrm(deviceId, ref srmCmd, false, toPlace, ref toZ, ref toX, ref toY);
|
|
|
//发送指令
|
var ss = this.plcService;
|
|
////只有一台堆垛机,不需要写
|
//var constValue = 1;
|
//MessageModel b1 = this.plcService.WriteValuePoint( this.DBBlockForWrite.W_SrmNo, constValue, this.View.W_SrmNo);
|
//if (!b1.result)
|
//{
|
// msg = string.Format("向堆垛机{0}发送任务{1},写入设备编号" + constValue + "失败,返回结果:" + b1.resMsg, this.View.DeviceName, taskId);
|
// return false;
|
//}
|
MessageModel b1 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_PalletType, pallettype, this.View.W_PalletType);
|
if (!b1.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入托盘类型" + pallettype + "失败,返回结果:" + b1.resMsg, this.View.DeviceName, taskId);
|
return false;
|
}
|
|
|
MessageModel b2 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_TaskNo, taskId, this.View.W_TaskNo);
|
if (!b2.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入任务号" + taskId + "失败,返回结果:" + b2.resMsg, this.View.DeviceName, taskId);
|
return false;
|
}
|
|
//MessageModel b60 = this.plcService.WriteValuePoint( this.DBBlockForWrite.W_PalletType, constValue, this.View.W_PalletType);
|
//if (!b60.result)
|
//{
|
// msg = string.Format("向堆垛机{0}发送任务{1},写入托盘类型" + constValue + "失败,返回结果:" + b60.resMsg, this.View.DeviceName, taskId);
|
// return false;
|
//}
|
|
if (srmCmd == ESrmCmd.库内搬运 || srmCmd == ESrmCmd.入库 || srmCmd == ESrmCmd.出库 || srmCmd == ESrmCmd.单取)
|
{
|
MessageModel b5 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_SourcePosZ, sourceZ, this.View.W_SourcePosZ);
|
if (!b5.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入sourceZ失败,返回结果:" + b5.resMsg, this.View.DeviceName, taskId);
|
return false;
|
}
|
|
MessageModel b4 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_SourcePosX, sourceX, this.View.W_SourcePosX);
|
if (!b4.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入sourceX失败,返回结果:" + b4.resMsg, this.View.DeviceName, taskId);
|
return false;
|
}
|
MessageModel b3 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_SourcePosY, sourceY, this.View.W_SourcePosY);
|
if (!b3.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入sourceY失败,返回结果:" + b3.resMsg, this.View.DeviceName, taskId);
|
return false;
|
}
|
}
|
|
|
MessageModel b8 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_DestinationPosZ, toZ, this.View.W_DestinationPosZ);
|
if (!b8.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入toZ失败,返回结果:" + b8.resMsg, this.View.DeviceName, taskId);
|
return false;
|
}
|
MessageModel b7 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_DestinationPosX, toX, this.View.W_DestinationPosX);
|
if (!b7.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入toX失败,返回结果:" + b7.resMsg, this.View.DeviceName, taskId);
|
return false;
|
}
|
MessageModel b6 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_DestinationPosY, toY, this.View.W_DestinationPosY);
|
if (!b6.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入toY失败,返回结果:" + b6.resMsg, this.View.DeviceName, taskId);
|
return false;
|
}
|
|
short command = (short)srmCmd;
|
MessageModel b10 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_Command, command, this.View.W_Command);
|
if (!b10.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入command失败,返回结果:" + b10.resMsg, this.View.DeviceName, taskId);
|
return false;
|
}
|
|
int verification = sourceX + sourceY + sourceZ + toX + toY + toZ + command;
|
MessageModel b11 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_Taskverification, verification, this.View.W_Taskverification);
|
if (!b11.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入任务校验失败,返回结果:" + b11.resMsg, this.View.DeviceName, verification);
|
return false;
|
}
|
|
MessageModel b9 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_Stb, 1, this.View.W_Stb);
|
if (!b9.result)
|
{
|
msg = string.Format("向堆垛机{0}发送任务{1},写入W_Stb失败,返回结果:" + b9.resMsg, this.View.DeviceName, taskId);
|
return false;
|
}
|
|
//重置如下状态
|
//不需要重置 【EditBy shaocx,2022-04-09】
|
//this.plcService.WriteValuePoint( this.DBBlockForWrite.W_EmergencyStop, 0, this.View.W_EmergencyStop);
|
//this.plcService.WriteValuePoint( this.DBBlockForWrite.W_CancleAlarm, 0, this.View.W_CancleAlarm);
|
//this.plcService.WriteValuePoint( this.DBBlockForWrite.W_TaskFinishConfirm, 0, this.View.W_TaskFinishConfirm);
|
//this.plcService.WriteValuePoint( this.DBBlockForWrite.W_Ack, 0, this.View.W_Ack);
|
|
return true;
|
}
|
catch (Exception ex)
|
{
|
msg = ex.Message;
|
Log4NetHelper.WriteErrorLog(Srm_CacheEntity.curLogType, "发送任务出现异常:" + ex.Message, ex);
|
return false;
|
}
|
}
|
|
|
/// <summary>
|
/// 堆垛机上的站点转换
|
/// </summary>
|
/// <param name="isSource"></param>
|
/// <param name="place"></param>
|
/// <param name="z"></param>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
private void ConvertPlaceToSrm(int deviceId, ref ESrmCmd srmCmd, bool isSource, string place, ref int z, ref int x, ref int y)
|
{
|
|
if (place == "03-01-01")
|
{//入口
|
x = 801;
|
y = 0;
|
z = 0;
|
|
if (isSource && srmCmd == ESrmCmd.库内搬运)
|
{//如果是起点是入库口
|
srmCmd = ESrmCmd.入库;
|
}
|
}
|
else if (place == "03-01-01")
|
{//出口
|
x = 901;
|
y = 0;
|
z = 0;
|
|
if (isSource == false && srmCmd == ESrmCmd.库内搬运)
|
{//如果是目标点是出口
|
srmCmd = ESrmCmd.出库;
|
}
|
}
|
|
}
|
|
|
/// <summary>
|
/// 任务删除
|
/// </summary>
|
/// <param name="srmNo"></param>
|
/// <param name="taskId"></param>
|
/// <param name="msg"></param>
|
/// <returns></returns>
|
public bool SendDelTask(int deviceId, out string msg)
|
{
|
try
|
{
|
msg = "";
|
|
if (!CanDeleteTask(deviceId, out msg))
|
{
|
return false;
|
}
|
|
MessageModel b3 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_Command, (int)ESrmCmd.任务删除, this.View.W_Command);
|
if (!(b3.result))
|
{
|
msg = string.Format("向堆垛机{0}发送删除任务失败,返回结果:" + b3.resMsg, this.View.DeviceName);
|
return false;
|
}
|
return true;
|
}
|
catch (Exception ex)
|
{
|
Log4NetHelper.WriteErrorLog(Srm_CacheEntity.curLogType, "任务删除出现异常:" + ex.Message, ex);
|
throw ex;
|
}
|
}
|
|
/// <summary>
|
/// 堆垛机解警
|
/// </summary>
|
/// <param name="msg"></param>
|
/// <returns></returns>
|
public bool ReleaseAlert(out string msg)
|
{
|
try
|
{
|
msg = "";
|
|
MessageModel b1 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_CancleAlarm, 1, this.View.W_CancleAlarm);
|
|
if (!(b1.result))
|
{
|
msg = string.Format("向堆垛机{0}发送解警指令失败,返回结果:" + b1.resMsg, this.View.DeviceName);
|
return false;
|
}
|
return true;
|
}
|
catch (Exception ex)
|
{
|
Log4NetHelper.WriteErrorLog(Srm_CacheEntity.curLogType, "发送解警指令异常:" + ex.Message, ex);
|
throw ex;
|
}
|
}
|
|
|
/// <summary>
|
/// 堆垛机急停
|
/// </summary>
|
/// <param name="msg"></param>
|
/// <returns></returns>
|
public bool SendEStop(out string msg)
|
{
|
try
|
{
|
msg = "";
|
|
MessageModel b1 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_EmergencyStop, 1, this.View.W_EmergencyStop);
|
|
if (!(b1.result))
|
{
|
msg = string.Format("向堆垛机{0}发送急停指令失败,返回结果:" + b1.resMsg, this.View.DeviceName);
|
return false;
|
}
|
return true;
|
}
|
catch (Exception ex)
|
{
|
Log4NetHelper.WriteErrorLog(Srm_CacheEntity.curLogType, "发送急停指令异常:" + ex.Message, ex);
|
throw ex;
|
}
|
}
|
|
/// <summary>
|
/// 堆垛机任务确认
|
/// </summary>
|
/// <param name="msg"></param>
|
/// <returns></returns>
|
public bool ConfirmTaskFinish(out string msg)
|
{
|
try
|
{
|
msg = "";
|
|
MessageModel b1 = this.plcService.WriteValuePoint(this.DBBlockForWrite.W_TaskFinishConfirm, 1, this.View.W_TaskFinishConfirm);
|
|
if (!(b1.result))
|
{
|
msg = string.Format("向堆垛机{0}发送任务确认指令失败,返回结果:" + b1.resMsg, this.View.DeviceName);
|
return false;
|
}
|
return true;
|
}
|
catch (Exception ex)
|
{
|
Log4NetHelper.WriteErrorLog(Srm_CacheEntity.curLogType, "发送任务确认指令异常:" + ex.Message, ex);
|
throw ex;
|
}
|
}
|
|
/// <summary>
|
/// 堆垛机继续任务
|
/// </summary>
|
/// <param name="msg"></param>
|
/// <returns></returns>
|
public bool ContinueTask(out string msg)
|
{
|
try
|
{
|
msg = "";
|
|
//var dbNumber = Srm_CacheEntity.W_DBHeader;
|
//FunctionReturnEntity b1 = this.S7.WriteValuePoint( this.DBBlock.con, 1);
|
|
//if (!(b1.result))
|
//{
|
// msg = string.Format("向堆垛机{0}发送解警指令失败,返回结果:" + b1.resMsg, this.DeviceName);
|
// return false;
|
//}
|
return true;
|
}
|
catch (Exception ex)
|
{
|
Log4NetHelper.WriteErrorLog(Srm_CacheEntity.curLogType, "堆垛机继续任务异常:" + ex.Message, ex);
|
throw ex;
|
}
|
}
|
|
/// <summary>
|
/// 是否可以下发任务
|
/// </summary>
|
/// <param name="deviceId"></param>
|
/// <param name="msg"></param>
|
/// <returns></returns>
|
public bool CanDoTask(int deviceId, out string msg, ESrmCmd? eSrmCmd = null)
|
{
|
msg = "";
|
//在不在线不需要校验,不在线的话
|
if (this.View.R_Mode != 1)
|
{
|
msg = string.Format("堆垛机{0}非自动模式", this.View.DeviceName);
|
return false;
|
}
|
|
if (this.View.R_Alarm == 1)
|
{
|
msg = string.Format("堆垛机{0}报警中", this.View.DeviceName);
|
return false;
|
}
|
|
if (eSrmCmd == ESrmCmd.出库 || eSrmCmd == ESrmCmd.入库 || eSrmCmd == ESrmCmd.单取 || eSrmCmd == ESrmCmd.库内搬运 || eSrmCmd == null)
|
{
|
if (this.View.R_LiftFull == 1)
|
{
|
msg = string.Format("堆垛机{0}叉齿有货", this.View.DeviceName);
|
return false;
|
}
|
if (this.View.R_State != (int)ESrmState.空闲)
|
{
|
msg = string.Format("堆垛机{0}非空闲", this.View.DeviceName);
|
return false;
|
}
|
}
|
|
if (this.View.R_PosZ != 0)
|
{
|
msg = string.Format("堆垛机{0}叉齿不在原点", this.View.DeviceName);
|
return false;
|
}
|
//*/
|
|
return true;
|
}
|
|
/// <summary>
|
/// 是否可以删除任务
|
/// </summary>
|
/// <param name="deviceId"></param>
|
/// <param name="msg"></param>
|
/// <returns></returns>
|
private bool CanDeleteTask(int deviceId, out string msg)
|
{
|
msg = "";
|
//在不在线不需要校验,不在线的话
|
if (this.View.R_Mode != 1)
|
{
|
msg = string.Format("堆垛机{0}非自动模式", this.View.DeviceName);
|
return false;
|
}
|
return true;
|
}
|
|
|
#endregion
|
|
public void SetPropertyValueForRead()
|
{
|
var r_dbBlock = this.DBBlockForRead;
|
SdaHelper.SetPropertyValueForDB<SrmDBForRead, SrmView>(r_dbBlock, this.View, this.plcService, "");
|
}
|
|
|
public void SetPropertyValueForWrite()
|
{
|
var w_dbBlock = this.DBBlockForWrite;
|
SdaHelper.SetPropertyValueForDB<SrmDBForWrite, SrmView>(w_dbBlock, this.View, this.plcService, "");
|
}
|
|
|
|
/// <summary>
|
/// 是否有心跳
|
/// </summary>
|
/// <returns></returns>
|
public bool IsHaveHeatBeat()
|
{
|
try
|
{
|
var r_dbBlock = this.DBBlockForRead;
|
short value = Convert.ToInt16(this.plcService.ReadValuePoint(r_dbBlock.R_HandShake, typeof(short)));
|
//约定 等待2秒
|
Thread.Sleep(2000);
|
short value_next = Convert.ToInt16(this.plcService.ReadValuePoint(r_dbBlock.R_HandShake, typeof(short)));
|
if (value == value_next)
|
{//没有心跳
|
return false;
|
}
|
else
|
{//有心跳
|
return true;
|
}
|
}
|
catch (Exception ex)
|
{
|
throw ex;
|
}
|
}
|
|
|
|
/// <summary>
|
/// 组合 起始点
|
/// </summary>
|
/// <returns></returns>
|
public string GetSrmSourcePlace()
|
{
|
if (this.View.W_SourcePosZ != 0)
|
{
|
return this.View.W_SourcePosZ.ToString("00") + "-" + this.View.W_SourcePosX.ToString("00") + "-" + this.View.W_SourcePosY.ToString("00");
|
}
|
|
return GetPlaceForInOutStation(this.View.W_SourcePosX);
|
}
|
/// <summary>
|
/// 组合 目标点
|
/// </summary>
|
/// <returns></returns>
|
public string GetSrmToPlace()
|
{
|
if (this.View.W_DestinationPosZ != 0)
|
{
|
return this.View.W_DestinationPosZ.ToString("00") + "-" + this.View.W_DestinationPosX.ToString("00") + "-" + this.View.W_DestinationPosY.ToString("00");
|
}
|
return GetPlaceForInOutStation(this.View.W_DestinationPosX);
|
}
|
|
/// <summary>
|
/// 单独获取出入口站点名
|
/// </summary>
|
/// <param name="xVaue"></param>
|
/// <returns></returns>
|
private string GetPlaceForInOutStation(short xVaue)
|
{
|
if (xVaue == 801)
|
{
|
return "01-01-01";
|
}
|
else if (xVaue == 901)
|
{
|
return "02-01-01";
|
}
|
return "";
|
}
|
|
|
#region 获取当前报警信息
|
|
|
|
/// <summary>
|
/// 获取当前报警信息
|
/// </summary>
|
/// <returns></returns>
|
public List<DeviceWarningInfo> GetAlertDatas()
|
{
|
List<DeviceWarningInfo> db_warningList = new List<DeviceWarningInfo>();
|
try
|
{
|
string _dbValue;
|
var isHasAlert = false;
|
IDictionary<string, string> srmAlertDict = new Dictionary<string, string>();
|
srmAlertDict = WareSdaStruct.SrmAlertDict;
|
foreach (var item in srmAlertDict)
|
{
|
_dbValue = item.Key;
|
isHasAlert = Convert.ToBoolean(this.plcService.ReadValuePoint(Srm_CacheEntity.R_DBHeader_Alert, item.Key, typeof(bool)));
|
if (isHasAlert)
|
{
|
db_warningList.Add(new DeviceWarningInfo()
|
{
|
Address = item.Key,
|
Code = item.Key,
|
Context = item.Value.Trim()
|
});
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
throw ex;
|
}
|
return db_warningList;
|
}
|
|
|
#endregion
|
}
|
}
|